# NousResearch/hermes-agent · Flag display in language selector debated

## Open now

- Nothing open on GitHub.

These items concern a bug where Traditional Chinese showed an incorrect flag, an attempted fix assigning a PRC flag, and a subsequent change to remove country flags from the language picker entirely. The members reflect an ongoing discussion about how to represent language options without implying national identity.

## TL;DR

- 3 member(s): 0 open issue(s), 1 closed issue(s), 0 open PR(s), 1 merged PR(s), 1 PR(s) closed without merging.
- A fix was merged to main in PR #29997. Verify it addresses your case.
- **Recommended:** read PR #29997 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `resolved` · deciding PR(s): `pr-29997`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_SPANNING`): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
- Pairwise link density `0.67`: the share of member pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. `1.00` means every pair is linked.

## Closed / duplicate issues

- #29750: \[Bug\]: Traditional Chinese (繁體中文) shows incorrect flag in language selector

## Prior & competing PRs

- **#29997: fix(dashboard): remove country flags from language picker**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`
  - files: `web/package.json`, `web/src/components/LanguageSwitcher.tsx`, `web/src/i18n/context.tsx`, `web/src/main.tsx`
  - fix hunks:
  - `web/package-lock.json`

    ```diff
    @@ -19,7 +19,6 @@
             "@xterm/xterm": "^6.0.0",
             "class-variance-authority": "^0.7.1",
             "clsx": "^2.1.1",
    -        "flag-icons": "^7.5.0",
             "gsap": "^3.15.0",
             "leva": "^0.10.1",
             "lucide-react": "^0.577.0",
    ```

    ```diff
    @@ -78,7 +77,6 @@
           "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
           "dev": true,
           "license": "MIT",
    -      "peer": true,
           "dependencies": {
             "@babel/code-frame": "^7.29.0",
             "@babel/generator": "^7.29.0",
    ```

    ```diff
    @@ -1129,7 +1127,6 @@
           "resolved": "https://registry.npmjs.org/@observablehq/plot/-/plot-0.6.17.tgz",
           "integrity": "sha512-/qaXP/7mc4MUS0s4cPPFASDRjtsWp85/TbfsciqDgU1HwYixbSbbytNuInD8AcTYC3xaxACgVX06agdfQy9W+g==",
           "license": "ISC",
    -      "peer": true,
           "dependencies": {
             "d3": "^7.9.0",
             "interval-tree-1d": "^1.0.0",
    ```

    ```diff
    @@ -1868,7 +1865,6 @@
           "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-9.6.0.tgz",
           "integrity": "sha512-90abYK2q5/qDM+GACs9zRvc5KhEEpEWqWlHSd64zTPNxg+9wCJvTfyD9x2so7hlQhjRYO1Fa6flR3BC/kpTFkA==",
           "license": "MIT",
    -      "peer": true,
           "dependencies": {
             "@babel/runtime": "^7.17.8",
             "@types/webxr": "*",
    ```

    ```diff
    @@ -2574,7 +2570,6 @@
           "integrity": "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==",
           "devOptional": true,
           "license": "MIT",
    -      "peer": true,
           "dependencies": {
             "undici-types": "~7.16.0"
           }
    ```

    ```diff
    @@ -2584,7 +2579,6 @@
           "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
           "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
           "license": "MIT",
    -      "peer": true,
           "dependencies": {
             "csstype": "^3.2.2"
           }
    ```

    ```diff
    @@ -2595,7 +2589,6 @@
           "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
           "devOptional": true,
           "license": "MIT",
    -      "peer": true,
           "peerDependencies": {
             "@types/react": "^19.2.0"
           }
    ```

    ```diff
    @@ -2660,7 +2653,6 @@
           "integrity": "sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==",
           "dev": true,
           "license": "MIT",
    -      "peer": true,
           "dependencies": {
             "@typescript-eslint/scope-manager": "8.59.1",
             "@typescript-eslint/types": "8.59.1",
    ```

    ```diff
    @@ -2989,7 +2981,6 @@
           "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
           "dev": true,
           "license": "MIT",
    -      "peer": true,
           "bin": {
             "acorn": "bin/acorn"
           },
    ```

    ```diff
    @@ -3142,7 +3133,6 @@
             }
           ],
           "license": "MIT",
    -      "peer": true,
           "dependencies": {
             "baseline-browser-mapping": "^2.10.12",
             "caniuse-lite": "^1.0.30001782",
    ```

    ```diff
    @@ -3650,7 +3640,6 @@
           "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
           "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
           "license": "ISC",
    -      "peer": true,
           "engines": {
             "node": ">=12"
           }
    ```

    ```diff
    @@ -3970,7 +3959,6 @@
           "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==",
           "dev": true,
           "license": "MIT",
    -      "peer": true,
           "dependencies": {
             "@eslint-community/eslint-utils": "^4.8.0",
             "@eslint-community/regexpp": "^4.12.1",
    ```

    ```diff
    @@ -4250,12 +4238,6 @@
             "url": "https://github.com/sponsors/sindresorhus"
           }
         },
    -    "node_modules/flag-icons": {
    -      "version": "7.5.0",
    -      "resolved": "https://registry.npmjs.org/flag-icons/-/flag-icons-7.5.0.tgz",
    -      "integrity": "sha512-kd+MNXviFIg5hijH766tt+3x76ele1AXlo4zDdCxIvqWZhKt4T83bOtxUOOMlTx/EcFdUMH5yvQgYlFh1EqqFg==",
    -      "license": "MIT"
    -    },
         "node_modules/flat-cache": {
           "version": "4.0.1",
           "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
    ```

    ```diff
    @@ -4382,8 +4364,7 @@
           "version": "3.15.0",
           "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.15.0.tgz",
           "integrity": "sha512-dMW4CWBTUK1AEEDeZc1g4xpPGIrSf9fJF960qbTZmN/QwZIWY5wgliS6JWl9/25fpTGJrMRtSjGtOmPnfjZB+A==",
    -      "license": "Standard 'no charge' license: https://gsap.com/standard-license.",
    -      "peer": true
    +      "license": "Standard 'no charge' license: https://gsap.com/standard-license."
         },
         "node_modules/has-flag": {
           "version": "4.0.0",
    ```

    ```diff
    @@ -4698,7 +4679,6 @@
           "resolved": "https://registry.npmjs.org/leva/-/leva-0.10.1.tgz",
           "integrity": "sha512-BcjnfUX8jpmwZUz2L7AfBtF9vn4ggTH33hmeufDULbP3YgNZ/C+ss/oO3stbrqRQyaOmRwy70y7BGTGO81S3rA==",
           "license": "MIT",
    -      "peer": true,
           "dependencies": {
             "@radix-ui/react-portal": "^1.1.4",
             "@radix-ui/react-tooltip": "^1.1.8",
    ```

    ```diff
    @@ -5106,7 +5086,6 @@
           "resolved": "https://registry.npmjs.org/motion/-/motion-12.39.0.tgz",
           "integrity": "sha512-H4a+Ze+a9j+/NTla5ezfb/g9vmIOxC+viDj++NGDZyTZkdRKjiOz3kSv6TalRWM8ZmD2y/CfC6TkQc97ybyqSA==",
           "license": "MIT",
    -      "peer": true,
           "dependencies": {
             "framer-motion": "^12.39.0",
             "tslib": "^2.4.0"
    ```

    ```diff
    @@ -5179,7 +5158,6 @@
             }
           ],
           "license": "MIT",
    -      "peer": true,
           "engines": {
             "node": "^20.0.0 || >=22.0.0"
           }
    ```

    ```diff
    @@ -5307,7 +5285,6 @@
           "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
           "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
           "license": "MIT",
    -      "peer": true,
           "engines": {
             "node": ">=12"
           },
    ```

    ```diff
    @@ -5379,7 +5356,6 @@
           "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz",
           "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==",
           "license": "MIT",
    -      "peer": true,
           "engines": {
             "node": ">=0.10.0"
           }
    ```

    ```diff
    @@ -5399,7 +5375,6 @@
           "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz",
           "integrity": "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==",
           "license": "MIT",
    -      "peer": true,
           "dependencies": {
             "scheduler": "^0.27.0"
           },
    ```

    ```diff
    @@ -5760,8 +5735,7 @@
           "version": "0.180.0",
           "resolved": "https://registry.npmjs.org/three/-/three-0.180.0.tgz",
           "integrity": "sha512-o+qycAMZrh+TsE01GqWUxUIKR1AL0S8pq7zDkYOQw8GqfX8b8VoCKYUoHbhiX5j+7hr8XsuHDVU6+gkQJQKg9w==",
    -      "license": "MIT",
    -      "peer": true
    +      "license": "MIT"
         },
         "node_modules/tinyglobby": {
           "version": "0.2.16",
    ```

    ```diff
    @@ -5826,7 +5800,6 @@
           "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
           "dev": true,
           "license": "Apache-2.0",
    -      "peer": true,
           "bin": {
             "tsc": "bin/tsc",
             "tsserver": "bin/tsserver"
    ```

    ```diff
    @@ -5925,7 +5898,6 @@
           "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
           "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
           "license": "MIT",
    -      "peer": true,
           "peerDependencies": {
             "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
           }
    ```

    ```diff
    @@ -5941,7 +5913,6 @@
           "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz",
           "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==",
           "license": "MIT",
    -      "peer": true,
           "dependencies": {
             "esbuild": "^0.27.0",
             "fdir": "^6.5.0",
    ```

    ```diff
    @@ -6063,7 +6034,6 @@
           "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
           "dev": true,
           "license": "MIT",
    -      "peer": true,
           "funding": {
             "url": "https://github.com/sponsors/colinhacks"
           }
    ```
  - `web/package.json`

    ```diff
    @@ -21,7 +21,6 @@
         "@xterm/xterm": "^6.0.0",
         "class-variance-authority": "^0.7.1",
         "clsx": "^2.1.1",
    -    "flag-icons": "^7.5.0",
         "gsap": "^3.15.0",
         "leva": "^0.10.1",
         "lucide-react": "^0.577.0",
    ```
  - `web/src/components/LanguageSwitcher.tsx`

    ```diff
    @@ -9,15 +9,16 @@ import type { Locale } from "@/i18n";
     import { cn } from "@/lib/utils";
     
     /**
    - * Language picker — shows the current language's flag + endonym, opens a
    - * dropdown of all supported locales when clicked.  Persists choice to
    - * localStorage via the I18n context.
    + * Language picker — shows the current language's endonym, opens a dropdown
    + * of all supported locales when clicked.  Persists choice to localStorage via
    + * the I18n context.
      *
      * Replaces the older two-state EN↔ZH toggle now that we ship 16 locales
      * (en, zh, zh-hant, ja, de, es, fr, tr, uk, af, ko, it, ga, pt, ru, hu).
      *
    - * Locale markers use lipis/flag-icons (SVG sprites) instead of emoji so flags
    - * render consistently across platforms.
    + * No country flags by design — languages aren't countries, and flag pairings
    + * inevitably create political mismappings (e.g. Mandarin variants ≠ any single
    + * jurisdiction, English ≠ GB, Portuguese ≠ PT). Endonyms are unambiguous.
      *
      * When placed at the bottom of the sidebar (next to ThemeSwitcher), pass
      * `dropUp` so the list opens above the trigger and avoids clipping below the
    ```

    ```diff
    @@ -71,7 +72,6 @@ export function LanguageSwitcher({ dropUp = false }: LanguageSwitcherProps) {
             className="px-2 py-1 normal-case tracking-normal font-normal text-xs text-muted-foreground hover:text-foreground"
           >
             <span className="inline-flex items-center gap-1.5">
    -          <LocaleFlagIcon countryCode={current.flagCountryCode} />
               <Typography
                 mondwest
                 className="hidden sm:inline tracking-wide uppercase text-[0.65rem]"
    ```

    ```diff
    @@ -146,8 +146,6 @@ function LanguageSwitcherOptions({
                 role="option"
                 type="button"
               >
    -            <LocaleFlagIcon countryCode={meta.flagCountryCode} />
    -
                 <span className="truncate">{meta.name}</span>
     
                 {selected && <span className="ml-auto text-xs">✓</span>}
    ```

    ```diff
    @@ -158,15 +156,6 @@ function LanguageSwitcherOptions({
       );
     }
     
    -function LocaleFlagIcon({ countryCode }: LocaleFlagIconProps) {
    -  return (
    -    <span
    -      aria-hidden
    -      className={cn("fi fis shrink-0 text-base leading-none", `fi-${countryCode}`)}
    -    />
    -  );
    -}
    -
     interface LanguageSwitcherOptionsProps {
       allLocales: Array<[Locale, (typeof LOCALE_META)[Locale]]>;
       locale: Locale;
    ```

    ```diff
    @@ -177,7 +166,3 @@ interface LanguageSwitcherOptionsProps {
     interface LanguageSwitcherProps {
       dropUp?: boolean;
     }
    -
    -interface LocaleFlagIconProps {
    -  countryCode: string;
    -}
    ```
  - `web/src/i18n/context.tsx`

    ```diff
    @@ -37,27 +37,31 @@ const TRANSLATIONS: Record<Locale, Translations> = {
     };
     
     // Display metadata for the language picker — endonym (native name) so users
    -// recognize their language even if they don't speak the current UI language,
    -// plus a flag-icons sprite (ISO 3166-1 alpha-2) for visual scanning.
    +// recognize their language even if they don't speak the current UI language.
     // Exposed as a constant so the LanguageSwitcher and any future settings page
     // can share the same list.
    -export const LOCALE_META: Record<Locale, { name: string; flagCountryCode: string }> = {
    -  en: { name: "English", flagCountryCode: "gb" },
    -  zh: { name: "简体中文", flagCountryCode: "cn" },
    -  "zh-hant": { name: "繁體中文", flagCountryCode: "tw" },
    -  ja: { name: "日本語", flagCountryCode: "jp" },
    -  de: { name: "Deutsch", flagCountryCode: "de" },
    -  es: { name: "Español", flagCountryCode: "es" },
    -  fr: { name: "Français", flagCountryCode: "fr" },
    -  tr: { name: "Türkçe", flagCountryCode: "tr" },
    -  uk: { name: "Українська", flagCountryCode: "ua" },
    -  af: { name: "Afrikaans", flagCountryCode: "za" },
    -  ko: { name: "한국어", flagCountryCode: "kr" },
    -  it: { name: "Italiano", flagCountryCode: "it" },
    -  ga: { name: "Gaeilge", flagCountryCode: "ie" },
    -  pt: { name: "Português", flagCountryCode: "pt" },
    -  ru: { name: "Русский", flagCountryCode: "ru" },
    -  hu: { name: "Magyar", flagCountryCode: "hu" },
    +//
    +// We intentionally do NOT pair locales with country flags. Languages are not
    +// countries (English ≠ GB, Portuguese ≠ PT, Spanish ≠ ES, Chinese variants ≠
    +// any single jurisdiction). Endonyms are unambiguous and avoid the political
    +// mismapping that flag pairings inevitably create.
    +export const LOCALE_META: Record<Locale, { name: string }> = {
    +  en: { name: "English" },
    +  zh: { name: "简体中文" },
    +  "zh-hant": { name: "繁體中文" },
    +  ja: { name: "日本語" },
    +  de: { name: "Deutsch" },
    +  es: { name: "Español" },
    +  fr: { name: "Français" },
    +  tr: { name: "Türkçe" },
    +  uk: { name: "Українська" },
    +  af: { name: "Afrikaans" },
    +  ko: { name: "한국어" },
    +  it: { name: "Italiano" },
    +  ga: { name: "Gaeilge" },
    +  pt: { name: "Português" },
    +  ru: { name: "Русский" },
    +  hu: { name: "Magyar" },
     };
     
     const SUPPORTED_LOCALES = Object.keys(TRANSLATIONS) as Locale[];
    ```
  - `web/src/main.tsx`

    ```diff
    @@ -1,6 +1,5 @@
     import { createRoot } from "react-dom/client";
     import { BrowserRouter } from "react-router-dom";
    -import "flag-icons/css/flag-icons.min.css";
     import "./index.css";
     import App from "./App";
     import { SystemActionsProvider } from "./contexts/SystemActions";
    ```
- **#29765: fix(web): show PRC flag for Traditional Chinese (繁體中文)**. closed without merge
  - maintainer direction: category `superseded_by_pr`; implication `superseded`; refs `#29997`

## Fix status

- Merged to main in PR #29997 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-05-21`.
