You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
i18n is disabled by default, preventing bundled translations from loading for all locales #24741
What version of the Codex App are you using (From “About Codex” dialog)?
26.519.81530 (3178)
What subscription do you have?
Plus
What platform is your computer?
Darwin 24.6.0 arm64 arm
What issue are you seeing?
Codex Desktop ships bundled translations and locale files for multiple locales, but the UI stays in English because i18n is gated behind the enable_i18n Statsig flag and its local fallback defaults to false.
This affects all bundled non-English locales, not only zh-CN. Even when the system locale is a supported locale, or localeOverride is set, the translated UI does not load unless the remote Statsig config explicitly enables enable_i18n.
I verified this locally by inspecting the packaged app. The i18n provider in the webview bundle reads the flag with a false fallback:
get(`enable_i18n`,false)
Changing only that fallback to true allows bundled translations to load.
What steps can reproduce the bug?
1. Install Codex Desktop version 26.519.81530 (3178).
2. Use a supported bundled non-English locale, for example:
- Set macOS system language/region to zh-CN, ja-JP, fr-FR, de-DE, etc.
- Or set Codex `localeOverride` to a supported locale such as `zh-CN`.
- Or launch with `ELECTRON_LOCALE_OVERRIDE=zh-CN`.
3. Restart Codex Desktop.
4. Observe that the UI remains English.
This is not tied to a specific conversation/session. It happens before any Codex session is needed.
What is the expected behavior?
When the system locale or localeOverride is set to a supported bundled locale, Codex Desktop should load that locale's translated UI by default.
Since the locale files are already bundled with the desktop app, users should not need a remote Statsig flag to be enabled before translations can appear.
Additional information
This bug has existed for a long time. I noticed that no one has attempted to fix this vulnerability yet, and this vulnerability has occurred multiple times in the issue section. I would like to submit a pull request to fix this issue.
I wrote a Python script to patch the local app.asar file, and then I was able to switch languages correctly.
Codex renderer/service processes are launched with --lang=zh-CN.
The app bundle includes zh-CN frontend translation assets and native-menu-locales/zh-CN.json.
Reinstalling Codex, fully restarting the app, and clearing Chromium/Electron cache did not help.
The visible app UI remains English.
Additional diagnosis:
The selected locale appears to be saved and propagated correctly. The problem looks consistent with the i18n provider not loading translated messages unless the remote Statsig gate/dynamic config enables enable_i18n. This also explains why another user on the same Codex version and also using API key auth can see Chinese UI, while this machine/account cannot.
Expected behavior:
If a supported locale is selected in Settings and localeOverride is set, Codex Desktop should load the bundled locale messages without requiring a per-account/per-device remote rollout flag.
After looking through existing issues, it turns out Codex Desktop already ships with a fairly complete zh-CN translation bundle (~6,000+ strings in webview/assets/zh-CN-*.js plus native-menu-locales/zh-CN.json). The original framing of this issue ("introduce an i18n layer") is therefore inaccurate — the i18n layer exists and the translations exist; they just don't load.
The actual root cause, already documented by other reporters, is that the i18n system is gated behind the Statsig flag enable_i18n, whose local fallback defaults to false. So even with:
OS locale set to zh-CN
localeOverride = "zh-CN" in config.toml
launching with --lang=zh-CN
ELECTRON_LOCALE_OVERRIDE=zh-CN
…the renderer still falls back to English because the i18n init code never activates.
Concrete asks (revised)
Flip the local fallback for enable_i18n to true, or remove the gate entirely now that the translations are shipped.
Make the web UI's i18n init read localeOverride / app.getLocale() / navigator.language instead of hard-coding en-US.
Document the supported locales and the localeOverride config key in user-facing docs.
Happy for maintainers to close this as a duplicate of whichever of the above they consider canonical (likely #24741). Leaving it open meanwhile in case the consolidated framing helps triage.
i18n never loads on Windows Store builds: root cause, complete evidence, and the one-line fix
App: Codex Desktop (Microsoft Store / MSIX) 26.924.2738.0 on Windows 11 (build 26200), system locale zh-CN, API-key auth mode. Symptom: with [desktop] localeOverride = "zh-CN" (and even with --lang=zh-CN), the renderer UI stays 100% English: sidebar (New chat / Scheduled / Plugins / Explore / Projects / Recents), the in-window menu bar labels (File / Edit / View / Help) and all settings text. The native dropdown menus and dialog strings are Chinese, so locale handling itself works - only the renderer's bundled translations never load.
Root cause
In the renderer bundle webview/assets/app-initial-*.js the i18n provider does:
so the locale chunk is only imported when enable_i18n is truthy, and the local fallback is false. The value comes from the Statsig dynamic config 72216192; the same module also reads locale_source from it. The settings page reads the same flag with a true default, which is why the language picker is visible and can be changed while the UI never switches.
Verified on the running app (renderer DevTools port)
__STATSIG__ exists and is the React SDK namespace (useDynamicConfig, useLayer, StatsigClient, firstInstance, instances, ...) - it has no getDynamicConfig/getLayer of its own; the client instances do.
The app reads the gate through the client layer: instrumenting the client methods captured getLayer(72216192) (plus many other ids).
The value it gets: __STATSIG__.firstInstance.getLayer('72216192').get('enable_i18n', 'MISSING') -> MISSING - the key is absent from the config object, so the false fallback applies.
Repeated with 6 freshly generated anonymous stable IDs (customIDs.stableID), each with a fresh evaluation: enable_i18n was MISSING every time. So the local server response simply does not carry the key; it is not a percentage-rollout membership problem of one particular device.
localeOverride is nevertheless applied: document.documentElement.lang === 'zh-CN', navigator.language === 'zh-CN', and the native application menu (from native-menu-locales/zh-CN.json) renders in Chinese.
The translations are definitely shipped: native-menu-locales/zh-CN.json, the renderer chunk webview/assets/zh-CN-1adc76a05252.js (~2 MB) and locales/zh-CN.pak all exist in the installed package.
The fix
Make the local fallback default to enabled, e.g.
l=c?.get('enable_i18n',!0)// was !1
or ship the same flag on in the local default config. Nothing else is needed: forcing exactly that value at runtime (injecting a wrapper around the client's getLayer for config 72216192) makes the whole UI render in Chinese immediately, menus included.
Please don't dismiss this as "works on my machine"
This is reported repeatedly (#23815, #19239, #24741, #24827, #27846, #29204, #30060) and it is fully deterministic on this machine: the flag simply never arrives, and the fallback is false. Users on API-key auth without access to OpenAI endpoints can never get the flag, because it depends on a remote evaluation that their environment may not receive.
Extra context (why local workarounds fail on 26.900+)
For anyone trying to work around this locally, note the walls in this build:
Files under C:\Program Files\WindowsApps\<package> cannot be written in place - even by an elevated administrator who has taken ownership and granted Administrators full control (Access Denied, reproducible in Safe Mode as well).
Editing a copy of the app does not help: for 26.900+ any single byte change in app.asar makes the app abort 2-5 s after launch with 0x80000003 (STATUS_BREAKPOINT). Verified: changing one semantically meaningless byte (a space to a tab) is enough.
--inspect is ignored by this build (no main-process inspector appears on the debugging port), so the main process cannot be patched at runtime.
CDP Page.addScriptToEvaluateOnNewDocument scripts do not run in the reloaded page (typeof window.__codexZhI18nDiag === 'undefined' after Page.reload), so renderer injection has to happen before script execution (instrumentation breakpoint / auto-attach) to be reliable.
Environment note: api.openai.com / chatgpt.com are unreachable from this network, while api.statsig.com / featuregates.org are reachable.
Activity
github-actions commentedon May 27, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
tangnomad commentedon Jun 16, 2026
I can still reproduce this on the latest Codex Desktop release.
Environment:
What I observed:
Additional diagnosis:
The selected locale appears to be saved and propagated correctly. The problem looks consistent with the i18n provider not loading translated messages unless the remote Statsig gate/dynamic config enables enable_i18n. This also explains why another user on the same Codex version and also using API key auth can see Chinese UI, while this machine/account cannot.
Expected behavior:
If a supported locale is selected in Settings and localeOverride is set, Codex Desktop should load the bundled locale messages without requiring a per-account/per-device remote rollout flag.
shilei-openclaw commentedon Jun 20, 2026
Update / re-scoping after further investigation
After looking through existing issues, it turns out Codex Desktop already ships with a fairly complete
zh-CNtranslation bundle (~6,000+ strings inwebview/assets/zh-CN-*.jsplusnative-menu-locales/zh-CN.json). The original framing of this issue ("introduce an i18n layer") is therefore inaccurate — the i18n layer exists and the translations exist; they just don't load.The actual root cause, already documented by other reporters, is that the i18n system is gated behind the Statsig flag
enable_i18n, whose local fallback defaults tofalse. So even with:zh-CNlocaleOverride = "zh-CN"inconfig.toml--lang=zh-CNELECTRON_LOCALE_OVERRIDE=zh-CN…the renderer still falls back to English because the i18n init code never activates.
Concrete asks (revised)
enable_i18ntotrue, or remove the gate entirely now that the translations are shipped.localeOverride/app.getLocale()/navigator.languageinstead of hard-codingen-US.localeOverrideconfig key in user-facing docs.Related / likely-duplicate issues
Happy for maintainers to close this as a duplicate of whichever of the above they consider canonical (likely #24741). Leaving it open meanwhile in case the consolidated framing helps triage.
Jeck164 commentedon Sep 29, 2026
i18n never loads on Windows Store builds: root cause, complete evidence, and the one-line fix
App: Codex Desktop (Microsoft Store / MSIX) 26.924.2738.0 on Windows 11 (build 26200), system locale zh-CN, API-key auth mode.
Symptom: with
[desktop] localeOverride = "zh-CN"(and even with--lang=zh-CN), the renderer UI stays 100% English: sidebar (New chat / Scheduled / Plugins / Explore / Projects / Recents), the in-window menu bar labels (File / Edit / View / Help) and all settings text. The native dropdown menus and dialog strings are Chinese, so locale handling itself works - only the renderer's bundled translations never load.Root cause
In the renderer bundle
webview/assets/app-initial-*.jsthe i18n provider does:so the locale chunk is only imported when
enable_i18nis truthy, and the local fallback isfalse. The value comes from the Statsig dynamic config72216192; the same module also readslocale_sourcefrom it. The settings page reads the same flag with atruedefault, which is why the language picker is visible and can be changed while the UI never switches.Verified on the running app (renderer DevTools port)
__STATSIG__exists and is the React SDK namespace (useDynamicConfig,useLayer,StatsigClient,firstInstance,instances, ...) - it has nogetDynamicConfig/getLayerof its own; the client instances do.getLayer(72216192)(plus many other ids).__STATSIG__.firstInstance.getLayer('72216192').get('enable_i18n', 'MISSING')->MISSING- the key is absent from the config object, so thefalsefallback applies.customIDs.stableID), each with a fresh evaluation:enable_i18nwasMISSINGevery time. So the local server response simply does not carry the key; it is not a percentage-rollout membership problem of one particular device.localeOverrideis nevertheless applied:document.documentElement.lang === 'zh-CN',navigator.language === 'zh-CN', and the native application menu (fromnative-menu-locales/zh-CN.json) renders in Chinese.native-menu-locales/zh-CN.json, the renderer chunkwebview/assets/zh-CN-1adc76a05252.js(~2 MB) andlocales/zh-CN.pakall exist in the installed package.The fix
Make the local fallback default to enabled, e.g.
or ship the same flag on in the local default config. Nothing else is needed: forcing exactly that value at runtime (injecting a wrapper around the client's
getLayerfor config72216192) makes the whole UI render in Chinese immediately, menus included.Please don't dismiss this as "works on my machine"
This is reported repeatedly (#23815, #19239, #24741, #24827, #27846, #29204, #30060) and it is fully deterministic on this machine: the flag simply never arrives, and the fallback is false. Users on API-key auth without access to OpenAI endpoints can never get the flag, because it depends on a remote evaluation that their environment may not receive.
Extra context (why local workarounds fail on 26.900+)
For anyone trying to work around this locally, note the walls in this build:
C:\Program Files\WindowsApps\<package>cannot be written in place - even by an elevated administrator who has taken ownership and granted Administrators full control (Access Denied, reproducible in Safe Mode as well).app.asarmakes the app abort 2-5 s after launch with0x80000003(STATUS_BREAKPOINT). Verified: changing one semantically meaningless byte (a space to a tab) is enough.--inspectis ignored by this build (no main-process inspector appears on the debugging port), so the main process cannot be patched at runtime.Page.addScriptToEvaluateOnNewDocumentscripts do not run in the reloaded page (typeof window.__codexZhI18nDiag === 'undefined'afterPage.reload), so renderer injection has to happen before script execution (instrumentation breakpoint / auto-attach) to be reliable.Environment note:
api.openai.com/chatgpt.comare unreachable from this network, whileapi.statsig.com/featuregates.orgare reachable.