plural-category: plural missing a CLDR category for the language
warning — advisory, exit 0
A plural in a translation is missing a category that the target language requires under CLDR. English needs only one/other, but Russian and Polish need one/few/many/other and Arabic needs zero/one/two/few/many/other. A plural that only carries one/other renders the wrong form for most quantities in those languages. The rule covers ICU MessageFormat plurals and key-based plurals: i18next suffixes (items_one, items_few…), Rails YAML one:/other:, Android <plurals> and .xcstrings plural variations. For key-based plurals the key set legitimately differs per language — Polish adds _few and _many, Japanese has only _other — so those keys are never reported as orphaned or missing.
What triggers it
// en.json (source)
{ "items": "{count, plural, one {# item} other {# items}}" }
// ru.json — only one/other; Russian needs few and many too
{ "items": "{count, plural, one {# элемент} other {# элементов}}" }Fixed
// ru.json
{ "items": "{count, plural, one {# элемент} few {# элемента} many {# элементов} other {# элемента}}" }
// i18next keys work the same way — pl.json
{ "items_one": "{{count}} produkt", "items_few": "{{count}} produkty",
"items_many": "{{count}} produktów", "items_other": "{{count}} produktu" }Why it matters
A key-set diff cannot see this bug: every key the source has is present, the placeholder is intact, and it still shows "5 элемент" to a Russian user because the many category was never written. The required categories are per-language and defined by CLDR, so a human reviewer rarely knows them by heart.
How to fix it
Add the missing categories for that language — for key-based plurals the finding names the exact keys to add. The categories come from CLDR (the same data `Intl.PluralRules` exposes), counted over whole numbers: French and Spanish are not asked for many, which only applies to millions. Applies to selectordinal and i18next _ordinal_ keys too.
How to silence it
It's a warning by default and never fails a build; --ignore-keys 'path.to.key' if a language intentionally simplifies a specific plural.
Check for this in CI
npx @shipi18n/cli check ./locales -s en
# SARIF for inline PR annotations:
npx @shipi18n/cli check ./locales -s en -r sarif -o shipi18n.sarifThe structural checks need no API key. Findings of this rule link back to this page from the SARIF helpUri.
What this looks like in your app
- A Flutter string renders without its placeholder — searched as “flutter arb placeholder missing at runtime”
- An ICU plural in one language throws at runtime — searched as “icu message format error in translation file”
Related rules
- plural-forms — plural forms lost in translation
- icu-invalid — translation is not valid ICU MessageFormat
- placeholder-missing — placeholder dropped from a translation