fix(i18n/build/ci): ICU-escape 381 message values, externalize tiktoken, add blocking UI-ICU gate - #12564
Open
chirag127 wants to merge 3 commits into
Open
Conversation
…s all catalogs
Messages containing raw `<tag>` or `{...}` literals fail to compile under
IntlMessageFormat (the parser next-intl uses) and silently break pages:
the component throws INVALID_MESSAGE and the UI falls back to showing the
raw key. Same class as diegosouzapw#12302 (ccOnboardingKeyPlaceholder), diegosouzapw#12505
(OMNIROUTE_AUTO_SYNC_CLAUDE_PROFILES.description) and diegosouzapw#12559
(featureFlagExposeFunctionalGatewayMirrorsDescription), all of which
shipped with these values.
Wrap every literal in ICU single quotes so it renders verbatim: file
paths, copy-paste JSON/regex hints, service-account JSON placeholders and
two `{" "}` status-label artifacts (phi/sv). The one deliberate wording
fix is a broken `<emdeze` rich-text tag in nl. Every change is asserted
render-identical (`format(fixed) === original`) by
scripts/ad-hoc/fix-invalid-icu.mjs.
381 message values changed across the 42 catalogs (the duplicate 'in'
locale was retired upstream by diegosouzapw#12496).
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
When tiktoken is bundled by Turbopack, its runtime fs.readFileSync lookup for tiktoken_bg.wasm (relative to __dirname) fails with "Missing tiktoken_bg.wasm", 500ing every route that touches codex-chatgpt-web token estimation (e.g. /api/providers). Externalize it like sqlite-vec / better-sqlite3 so the require stays at runtime. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
check:ui-icu compiles EVERY message value in every catalog
(src/i18n/messages/*.json) with IntlMessageFormat — the exact parser
next-intl uses. Any message that fails to compile (raw <tag>, literal
{...}) would silently break its page at runtime (the RSC path throws
INVALID_MESSAGE and the UI shows the raw key), so fail the PR instead.
The diegosouzapw#12302/diegosouzapw#12505/diegosouzapw#12559 defect class shipped 381 such values across the
catalogs; commit f85fc11 fixed them all. This gate runs in the blocking
i18n-ui-coverage job and pins the pure core (findInvalidMessages /
flattenLeaves) with unit tests (tests/unit/i18n-ui-icu.test.ts).
Legitimate t.rich rich-text messages (<b>bold</b>) and normal ICU
({count, plural, ...}) compile fine — no false positives.
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three tightly-related fixes, verified live on the latest
release/v3.8.51:fix(i18n)— ICU-escape 381 message values containing raw<tag>/ literal{...}across all 42 locale catalogs (src/i18n/messages/*.json).fix(build)— externalizetiktokeninnext.config.mjssotiktoken_bg.wasmresolves at runtime.chore(ci)— add a blockingcheck:ui-icugate that compiles every message value withIntlMessageFormat(next-intl's parser), so this defect class can never ship again.Background
A message value containing a raw
<tag>or literal{...}fails to compile underIntlMessageFormat. At runtime the component silently breaks — the RSC/Flight path throwsINVALID_MESSAGEand the UI falls back to showing the raw i18n key. This exact class shipped repeatedly:ccOnboardingKeyPlaceholder=<your OmniRoute API key>(crashed the Claude Code onboarding block)OMNIROUTE_AUTO_SYNC_CLAUDE_PROFILES.description=~/.claude/profiles/<name>/settings.json(Feature Flags page showed the raw key)<gateway-alias>/<model>tag in featureFlagExposeFunctionalGatewayMirrorsDescription (all 43 locales) breaks the Feature Flags page #12559 —featureFlagExposeFunctionalGatewayMirrorsDescription= raw<gateway-alias>/<model>[{ json, name?, email? }...]), a service-account JSON placeholder, regex samples, a broken<emdezerich-text tag innl, and two{" "}status-label artifacts (phi/sv)The fix (commit 1)
Every literal is wrapped in ICU single quotes so it renders verbatim — required here because the values are copy-paste content (file paths, JSON, regex), where real
</>/{characters must render. HTML entities would corrupt the pasted content. Every single change was asserted render-identical (new IntlMessageFormat(fixed).format() === original) byscripts/ad-hoc/fix-invalid-icu.mjs; the only deliberate wording change is thenl<emdezetypo correction.The duplicate
'in'locale was retired upstream in #12496, so the sweep covers the current 42 catalogs.The gate (commit 3)
npm run check:ui-icu→scripts/i18n/check-ui-icu.mjscompiles all 545,817 messages across 42 catalogs. Legitimatet.richrich-text ("<b>bold</b>") and normal ICU ({count, plural, ...}) compile fine — no false positives, pinned bytests/unit/i18n-ui-icu.test.ts(10 tests). Wired into the blockingi18n-ui-coveragejob in.github/workflows/ci.yml.The tiktoken fix (commit 2)
tiktokenresolvestiktoken_bg.wasmat runtime viafs.readFileSyncrelative to__dirname; bundled by Turbopack that lookup fails ("Missing tiktoken_bg.wasm") and 500s every route touching codex-chatgpt-web token estimation (e.g.GET /api/providers). Externalizing it (likesqlite-vec/better-sqlite3) keeps the require at runtime.Verification
check:ui-icu→ PASS — all 545,817 messages in 42 catalogs compiletests/unit/i18n-ui-icu.test.ts→ 10/10 passcheck-ui-value-drift(against base) → PASScheck-ui-keys-coverage→ PASSNote:
intl-messageformatis currently a transitive dep ofnext-intl(^11.1.0) — the gate requires it, so if that dependency is ever dropped it should be promoted to a direct dependency.