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
fix(spec): reject the retired `key`/`defaultValue` spellings in inline locale maps BY NAME, in any combination — and stop claiming the retired form "resolves to nothing" (#10492)
6
+
7
+
Two legs, both on `InlineLocaleMapSchema` in `packages/spec/src/ui/i18n.zod.ts`:
8
+
9
+
1.**Message accuracy.** The `INLINE_LOCALE_KEY` rejection message said the
10
+
retired key-reference form (#5055) "resolves to nothing". Measured false:
11
+
both resolvers — `resolveI18nLabel` here and objectui's `pickLocalized`,
12
+
parity-pinned — fall through to their last resort (first string value, in
13
+
key insertion order) and return the raw dotted key, which renders as the
14
+
visible label. The message now states the measured behaviour.
15
+
16
+
2.**Enforcement hole closed.**`key` is three letters — syntactically a valid
17
+
BCP-47 primary subtag — so `{ key: 'common.save' }` alone parsed as a
18
+
"language `key` inline locale map" and painted `common.save` on screen; the
19
+
pair form was rejected only because `defaultValue` fails the tag grammar.
20
+
The key pattern now refuses the two retired spellings by name, in any
21
+
combination, matching the emitted type's `{ key?: never; defaultValue?:
22
+
never }` narrowing (#9925, maintainer ruling 2026-08-19, option B). This is
23
+
an enforcement gap of the #5055 retirement, not a new contract: nothing else
24
+
is denied — real 2–3 letter subtags (`deu`, `fra`, `yue`) still parse.
25
+
26
+
FROM → TO: a label authored as `{ key: '<i18n.key>' }` (or any inline map
27
+
carrying a `key`/`defaultValue` entry) is now refused at parse time with the
28
+
named message; write the inline locale map form `{ en: '…', 'zh-CN': '…' }`,
29
+
or a plain string resolved through a translation bundle. This is the same
30
+
prescription the #5055 retirement and the #9925 type narrowing already carry —
31
+
the runtime now enforces what the type already refused.
32
+
33
+
<!-- adr-0087: not-required (already-registered ui-widget-i18n-family-retired) the key-reference dialect's retirement record already carries this prescription; this change closes its runtime enforcement gap, no new migration -->
0 commit comments