stalwartlabs/stalwart · error

{key}: {language} has no plural categories while other langu

Error message

{key}: {language} has no plural categories while other languages do: {value:?}

What it means

During locale code generation, the build script detects translation keys that use plural categories (`one=...;other=...`) in at least one language, and then requires every language to provide the same plural-form syntax. If a language's value cannot be split into `category=text` segments (split_plural_forms returns None), it panics naming the key, language, and offending value. This keeps plural handling consistent across locales at build time.

Source

Thrown at crates/common/build.rs:94

                .filter(|(name, _)| PLURAL_CATEGORIES.contains(name))
        })
        .collect()
}

fn plural_keys(locales: &HashMap<String, HashMap<String, String>>) -> HashSet<String> {
    let mut keys = HashSet::new();

    for (key, translations) in locales {
        if !translations
            .values()
            .any(|value| split_plural_forms(value).is_some())
        {
            continue;
        }

        for (language, value) in translations {
            let Some(forms) = split_plural_forms(value) else {
                panic!(
                    "{key}: {language} has no plural categories while other languages do: {value:?}"
                );
            };
            let mut seen = HashSet::new();
            for (name, _) in &forms {
                if !seen.insert(*name) {
                    panic!("{key}: {language} repeats the plural category {name:?}");
                }
            }
            if !seen.contains("other") {
                panic!("{key}: {language} is missing the required \"other\" plural category");
            }
        }

        keys.insert(key.clone());
    }

    keys

View on GitHub (pinned to e962003857)

Solutions

  1. Open i18n.yml at the key named in the panic and rewrite the `{language}` value using `zero=/one=/two=/few=/many=/other=` segments separated by `;`.
  2. Ensure at least an `other=` category is present for that language.
  3. If the key should not be pluralized at all, convert ALL languages' values for that key to plain strings.
  4. Only use the six valid plural category names; anything else fails the split.

Example fix

# before
key.name:
  en: one={count} item;other={count} items
  de: {count} Artikel
# after
key.name:
  en: one={count} item;other={count} items
  de: one={count} Artikel;other={count} Artikel
Defensive patterns

Strategy: validation

Validate before calling

// validate every pluralized value has cat=text segments before committing i18n.yml
for (key, translations) in &locales {
    if translations.values().any(|v| split_plural_forms(v).is_some()) {
        for (lang, v) in translations {
            assert!(split_plural_forms(v).is_some(), "{key}: {lang} lacks plural forms");
        }
    }
}

Try / catch

// build-time panic; run the parser as a unit test to get a clean failure:
#[test]
fn i18n_yaml_plural_consistency() { /* call plural_keys(&locales) and assert no panic */ }

Prevention

When it happens

Trigger: Editing `resources/locales/i18n.yml` so that one language for a pluralized key contains a plain string (no `cat=...;cat=...` segments), while other languages for that key contain valid plural forms. Also triggered by malformed syntax such as missing `=`, or using category names outside the allowed set (zero, one, two, few, many, other).

Common situations: A translator pastes a plain sentence into a field that is pluralized elsewhere; a new language entry is added as simple text while the key is plural in English; someone edits the value and accidentally breaks the `category=value;` format.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of stalwartlabs/stalwart@e962003857 (2026-09-06). Data as JSON: /api/errors/915e7c4422487afe. Report an issue: GitHub.