{"record":{"id":"16e9b11fb916b99d","repo":"stalwartlabs/stalwart","slug":"key-language-is-missing-the-required-other","errorCode":null,"errorMessage":"{key}: {language} is missing the required \"other\" plural category","messagePattern":"(.+?): (.+?) is missing the required \"other\" plural category","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/build.rs","lineNumber":105,"sourceCode":"            .any(|value| split_plural_forms(value).is_some())\n        {\n            continue;\n        }\n\n        for (language, value) in translations {\n            let Some(forms) = split_plural_forms(value) else {\n                panic!(\n                    \"{key}: {language} has no plural categories while other languages do: {value:?}\"\n                );\n            };\n            let mut seen = HashSet::new();\n            for (name, _) in &forms {\n                if !seen.insert(*name) {\n                    panic!(\"{key}: {language} repeats the plural category {name:?}\");\n                }\n            }\n            if !seen.contains(\"other\") {\n                panic!(\"{key}: {language} is missing the required \\\"other\\\" plural category\");\n            }\n        }\n\n        keys.insert(key.clone());\n    }\n\n    keys\n}\n\nfn plural_forms_literal(value: &str) -> String {\n    let forms = split_plural_forms(value).expect(\"validated above\");\n    let other = forms\n        .iter()\n        .find(|(name, _)| *name == \"other\")\n        .map(|(_, text)| *text)\n        .expect(\"validated above\");\n\n    let mut literal = String::from(\"PluralForms {\");","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/stalwartlabs/stalwart/blob/e96200385781a6a9995a8b839ac27d6c75a983ee/crates/common/build.rs#L87-L123","documentation":"Every pluralized translation value must include the `other` category, which serves as the fallback form in the generated plural lookup. After checking for duplicates, the build script verifies the collected set contains `other`; if not it panics for that key/language. CLDR plural rules always require an `other` form, so a value without one cannot be compiled.","triggerScenarios":"A language's value for a pluralized key lists categories like `one=...;few=...` but omits `other=...` in `resources/locales/i18n.yml`.","commonSituations":"Translators add only the categories they consider natural for their language (e.g. one/few for Slavic languages) and skip the fallback; partial edits truncate the value after the last `;`.","solutions":["Add an `other=<fallback text>` segment to the value for the named key/language in i18n.yml.","If the fallback text is the same as another category's, duplicate that text under `other=`.","Re-run the build to confirm the fix."],"exampleFix":"# before\n  pl: one={count} plik;few={count} pliki\n# after\n  pl: one={count} plik;few={count} pliki;other={count} plików","handlingStrategy":"validation","validationCode":"let cats: HashSet<&str> = value.split(';').filter_map(|s| s.split_once('=').map(|(n, _)| n)).collect();\nassert!(cats.contains(\"other\"), \"value must include an 'other' plural category\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include `other=` as the final segment of any pluralized value.","Treat `other` as the required fallback even for languages with rich plural systems.","Add a pre-commit check that every pluralized value contains `other=`."],"tags":["build-script","i18n","pluralization","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"e96200385781a6a9995a8b839ac27d6c75a983ee","analyzedAt":"2026-09-06T22:07:17.982Z","contentChangedAt":"2026-09-06T22:07:17.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}