Skip to content

fix(i18n): nest the catalog keys that were written with dots in their names - #28018

Closed
smwbev wants to merge 2 commits into
stablyai:mainfrom
smwbev:fix/i18n-nest-dotted-catalog-keys
Closed

smwbev wants to merge 2 commits into
stablyai:mainfrom
smwbev:fix/i18n-nest-dotted-catalog-keys

Conversation

@smwbev

@smwbev smwbev commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

ELI5

Orca keeps its interface text in a tree: settings, then agents, then save. Twelve entries were filed at the top of that tree under one long name, settings.agents.save, instead of in their place. Orca itself still finds them. A community language pack is not allowed to use names like that, so it cannot translate those strings the way the catalog writes them. This PR files the twelve where they belong and adds a check so it does not happen again.

What Changed

  • The eleven settings.agents.* strings from Edit agent launch settings on the workspace host #26479 move from the root of the catalog into the existing nested settings.agents object, in en, es, fr, ja, ko and zh.
  • The root settings.appearance.chat.title entry in en.json (from Add chat appearance settings: text size, code size, width #25657) is deleted. The nested entry with the same text was already there.
  • verify-localization-catalog.mjs now fails when a key in en.json or in a target catalog has a dot in its name, and lists the offending paths.
  • Review follow-up, second commit: five of the eleven strings in zh.json now call an agent 智能体, the word the rest of the Chinese catalog uses, instead of 代理, which reads as "proxy" (loadingHost, updateHost, readFailed, saveFailed, hostDefaults).

Nothing a user sees changes in English, Spanish, French, Japanese or Korean: the flattened path → value map of those five catalogs is identical on both sides, and en.json has 15,813 paths either way. In Chinese every path is the same and five values differ, the ones named above. No call site is touched.

Why

The built-in locales never noticed the flat entries. i18next falls back to a flat key when the nested path is missing, and the verifier flattens both shapes to the same dotted path.

Language packs do notice. parsePluginLanguagePackArtifact rejects any catalog key that contains a dot (hasUnsafeCatalogKeyCharacter), and one rejected key rejects the whole pack:

{"settings.agents.save": "…"}              → catalog key settings.agents.save is not safe
{"settings": {"agents": {"save": "…"}}}    → accepted

A pack that mirrors en.json already fails to load on v1.4.223 and v1.4.224 because of the duplicate chat.title entry, and a pack that drops such keys would leave the eleven host agent-settings strings in English once #26479 ships. The eleven are not in a release yet, so nesting them now means no pack author has to special-case them.

Two alternatives I did not take:

  • Let the pack parser accept dotted keys. That loosens a safety rule to accommodate twelve catalog entries, and leaves two ways to address every string.
  • Make --fix rewrite dotted keys. sync:localization-catalog already writes nested keys (setCatalogEntry splits on the dot), so these twelve did not come from it. A failing check that lists the paths is enough.

Linked Issue

Fixes #28017

First raised in #10592 (details, confirmation from the Traditional Chinese pack).

Visual Proof

N/A. No layout or interaction change: the catalogs hold the same paths, only stored nested, and i18next returns the same text for all twelve keys in five locales. In Chinese, five of them now read 智能体 where they read 代理.

Testing

  • I manually tested these changes locally
  • Automated tests added/updated, or explained why not below

I did not launch the app: there is no behavior to observe. The catalogs are compared as data instead.

  • The verifier with the new check, run against the catalogs on main (cef4d29096), exits 1 and lists the twelve paths for en.json. On this branch it exits 0.
  • New test rejects a key that carries its path in a dotted name covers en.json, a target catalog, and that --fix leaves the file alone.
  • A script comparing the flattened path → value map of each catalog before and after: 0 differences in en, es, fr, ja and ko; in zh, the five reworded values and nothing else.
  • pnpm lint and pnpm typecheck pass, and so do the five verify:localization-* scripts.
  • vitest run under Node over config/scripts, src/renderer/src/i18n and src/shared/plugins: 378 files. Two fail, ensure-native-runtime and patched-dependencies-frozen-install, and both fail the same way on a clean checkout of main on this machine.
  • pnpm test and pnpm build were not run. The pnpm test wrapper runs Vitest on Bun, and this machine has Bun 1.3.14 rather than the pinned 1.4.2.

Run on macOS. The change is JSON and a Node script; nothing in it is platform-specific.

AI Disclosure

Claude Opus 5.5 in Claude Code made the change and ran the checks listed above. I directed the work and approved publishing it.

Review

Self-review, by risk:

  • Lost or changed strings. The catalogs were compared as flattened maps before and after. Five are identical, and zh differs only in the five values reworded in review, so nothing was dropped or renamed.
  • The Chinese wording. It is the repository's own, not a fresh translation: locale-phrase-fixes.mjs rewrites 代理 to 智能体 when the English says "agent", and repairCatalog run over zh.json produces exactly these five values.
  • The new check. It walks keys, not values, so a value containing a dot is not flagged. It runs before --fix does anything and never rewrites a file.
  • Other open work. The branch merges cleanly with main and with fix(i18n): select whole count sentences at twelve more call sites #27974 and chore(i18n): retire unreferenced catalog keys and gate the scan #19801, which also touch the catalogs.

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

Catalog data and a lint-time check only. No runtime code, no platform, SSH or mobile impact. Existing installs are unaffected: the keys the code asks for resolve to the same text, and the five reworded Chinese strings are not in a release yet.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred) — lint and typecheck pass locally; test and build left to CI, see Testing

… names

Twelve entries in en.json sat at the root under a name that spells out
the whole path ("settings.agents.save") instead of inside the nested
settings object. Eleven of them, the host agent-settings strings from
stablyai#26479, were flat in es, fr, ja, ko and zh as well. The twelfth
duplicated the nested settings.appearance.chat.title.

Built-in locales rendered them anyway, because i18next falls back to a
flat key when the nested path is missing. A language pack cannot use
that shape: the pack parser rejects any key that contains a dot, and
one rejected key rejects the whole catalog.

The eleven strings now live in settings.agents in all six catalogs and
the duplicate is gone. Every path and value is unchanged, so no call
site moves. The catalog verifier now fails on a key with a dot in its
name, in en.json and in the target catalogs.
@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9bf7bf1d-5ec1-455a-a926-94086cae420e

📥 Commits

Reviewing files that changed from the base of the PR and between 7472d9a and fa09fa1.


📒 Files selected for processing (1)
  • src/renderer/src/i18n/locales/zh.json

🚧 Files skipped from review as they are similar to previous changes (1)
  • src/renderer/src/i18n/locales/zh.json

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.



📝 Walkthrough
📝 Walkthrough

Walkthrough

The locale catalogs now store agent settings translations as nested properties instead of flat dotted keys. The English catalog also removes a flat appearance translation. The verifier rejects dotted keys in the English catalog before collecting references and in each locale catalog before parity validation. Tests cover dotted keys in English fix mode and Spanish validation mode.


Priority: ➖ Normal

Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to fa09f

No outstanding issue is established by the supplied changes; the PR is mergeable after normal checks.

Pre-merge checks | Passed 2 | Failed 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check Warning Issue #28017 requires the twelve entries to move to nested objects while preserving their paths and values. The verifier and test implement the dotted-key requirement, and the catalogs move the entrie… Revert the five Chinese value changes to the pre-PR values, while retaining the nested catalog structure, duplicate removal, verifier check, and test.
Out of Scope Changes check Warning The five Chinese terminology changes in zh.json are not needed to prevent dotted catalog keys or to add the verifier check. They change user-visible translations and are separate from the linked iss… Remove the unrelated 代理 to 智能体 translation changes from this pull request, or link a separate coding requirement that authorizes that translation update.
Docstring Coverage Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 2 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check Passed The title clearly identifies the primary change: nesting localization catalog keys that were incorrectly stored with dots in their names.
Description check Passed The description is complete and structured according to the repository template. It explains the change, reason, linked issue, testing, AI usage, review notes, scope, and checklist status. It also exp…

Full details: Linked Issues check

Explanation

Issue #28017 requires the twelve entries to move to nested objects while preserving their paths and values. The verifier and test implement the dotted-key requirement, and the catalogs move the entries correctly. However, zh.json changes five values from 代理 to 智能体 for loadingHost, updateHost, readFailed, saveFailed, and hostDefaults. This does not preserve all values requested by #28017.


Full details: Out of Scope Changes check

Explanation

The five Chinese terminology changes in zh.json are not needed to prevent dotted catalog keys or to add the verifier check. They change user-visible translations and are separate from the linked issue's requested data-shape correction. The remaining catalog, verifier, and test changes support #28017.


Full details: Docstring Coverage

Explanation

Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 2 files. (1 skipped: 1 unsupported.)


  • Fix all pre-merge checks with AI
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d80c46ac-1315-42c8-a0e8-aacae93ae161
📥 Commits

Reviewing files that changed from the base of the PR and between 3d27142 and 7472d9a.

📒 Files selected for processing (8)
  • config/scripts/verify-localization-catalog.mjs
  • config/scripts/verify-localization-catalog.test.mjs
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/fr.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Comment thread src/renderer/src/i18n/locales/zh.json Outdated
…tings strings

Five of the eleven strings this branch nests said 代理 for "agent" in
zh.json. The rest of the Chinese catalog calls an agent 智能体 and keeps
代理 for proxy and user-agent copy, so 代理设置 read as "proxy settings".
The new wording is what the catalog's own repair policy
(locale-phrase-fixes.mjs) produces for these five strings.

Raised by CodeRabbit in review. Only zh.json changes, and only these
five values.
@smwbev

smwbev commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #28251, which landed the same change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Twelve catalog keys are stored with dots in their names, a shape language packs cannot use

1 participant