Skip to content

PILOT_COUNT_ZERO is dead in all 14 locales (uppercase _ZERO never matches Intl.PluralRules lowercase categories) #45

@kgNatx

Description

@kgNatx

Severity: P3 | Subsystem: i18n-sw | Category: i18n

Location: /home/kyleg/containers/atxfpv.org/skwad/static/locales/en.json:PILOT_COUNT_ZERO entry

What

tPlural builds the lookup key as key + '_' + rule where rule = Intl.PluralRules(lang).select(count) (i18n.js:34-37). Intl returns lowercase CLDR categories ('zero','one','two','few','many','other'), never the uppercase 'ZERO'. Every locale defines PILOT_COUNT_ZERO (uppercase) — confirmed present in all 14 files — so that string is unreachable. Additionally, English PluralRules has only ['one','other'] categories (verified via node), so count=0 selects 'other' and renders PILOT_COUNT_other = "0 PILOTS" rather than the special PILOT_COUNT_ZERO = "0 PILOTS". The only caller is app.js:2738 ($('pilot-count').textContent = tPlural('PILOT_COUNT', count)). Net effect: dead key plus a latent trap — if anyone later relies on a true zero category (e.g., a locale that has one), the uppercase key would still never match. Functionally harmless today because en's _other text already reads "0 PILOTS".

Suggested fix

Either delete PILOT_COUNT_ZERO from all locales (simplest — it's never reachable), or rename to lowercase PILOT_COUNT_zero AND only add it for locales whose Intl.PluralRules actually expose a 'zero' category (none of the current 14 do).

Verification

Traced the full path. tPlural (i18n.js:34-37) builds the lookup as key + '' + rule where rule = Intl.PluralRules(currentLang).select(count), which returns lowercase CLDR categories. The fallback chain is strings[lang][key+''+rule] || strings[lang][key+'_other'] — it never references _ZERO. All 14 locale files define the uppercase PILOT_COUNT_ZERO (confirmed 14/14 via grep). I verified via node that none of the 14 supported locales even expose a 'zero' plural category, and that count=0 selects 'other' (en/ja/zh/etc.), 'one' (fr), or 'many' (pl). So PILOT_COUNT_ZERO is unreachable in every locale — confirmed dead key. The only caller is app.js:2738. Impact is purely dead config: count=0 still renders correctly via _other (or _one for fr, which is the correct French convention), so there is no user-facing breakage today. The 'latent trap' framing is mild overstatement since a future zero-category locale would need the lowercase key regardless. P3 is correct — no functional impact, just dead keys and a naming inconsistency.

Filed from the 2026-05-30 multi-agent codebase review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low priorityenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions