{"record":{"id":"ce99f56f21ac303f","repo":"Humanizr/Humanizer","slug":"locale-localecode-phrases-must-be-a-mapping","errorCode":null,"errorMessage":"Locale '{localeCode}.phrases' must be a mapping.","messagePattern":"Locale '(.+?)\\.phrases' must be a mapping\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Humanizer.SourceGenerators/Common/LocaleYamlCatalog.cs","lineNumber":773,"sourceCode":"                ? null\n                : grammarValue as SimpleYamlMapping\n                ?? throw new InvalidOperationException($\"Locale '{localeCode}.grammar' must be a mapping.\");\n        }\n\n        static LocalePhraseCatalog? ResolvePhraseCatalog(\n            string localeCode,\n            ImmutableDictionary<string, SimpleYamlValue> features)\n        {\n            var preserveDurationCaseForms =\n                features.TryGetValue(\"formatter\", out var formatterValue) &&\n                formatterValue is SimpleYamlMapping formatter &&\n                formatter.GetScalar(\"casePluralRule\") is not null;\n\n            return !features.TryGetValue(\"phrases\", out var phraseValue)\n                ? null\n                : phraseValue is SimpleYamlMapping mapping\n                ? LocalePhraseNormalization.Create(localeCode, mapping, preserveDurationCaseForms)\n                : throw new InvalidOperationException($\"Locale '{localeCode}.phrases' must be a mapping.\");\n        }\n\n        static HeadingSet? ResolveHeadings(\n            string localeCode,\n            ImmutableDictionary<string, SimpleYamlValue> features)\n        {\n            if (!features.TryGetValue(\"headings\", out var headingValue))\n            {\n                return null;\n            }\n\n            if (headingValue is not SimpleYamlMapping mapping)\n            {\n                throw new InvalidOperationException($\"Locale '{localeCode}.headings' must be a mapping.\");\n            }\n\n            foreach (var property in mapping.Values.Keys.Where(static property => property is not (\"full\" or \"short\")))\n            {","sourceCodeStart":755,"sourceCodeEnd":791,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer.SourceGenerators/Common/LocaleYamlCatalog.cs#L755-L791","documentation":"The 'phrases' feature holds localized phrase templates as a mapping keyed by phrase identifier. Only a YAML mapping is valid here; a scalar or sequence cannot represent keyed phrase entries, so the phrase catalog resolver throws.","triggerScenarios":"A locale file provides 'phrases:' as a scalar string or as a YAML sequence rather than a mapping of phrase-key to content.","commonSituations":"Editing phrase data and accidentally flattening the structure; misindenting phrase entries so they parse as a sequence; leaving a placeholder scalar.","solutions":["Restructure the 'phrases:' value as a mapping where each key is a phrase identifier and each value is the localized template.","Remove the 'phrases:' key if the locale has no phrase data.","Validate indentation so phrase entries nest under the mapping, not as list items."],"exampleFix":"# before\nphrases:\n  - Hello\n\n# after\nphrases:\n  greeting: Hello","handlingStrategy":"validation","validationCode":"import yaml, pathlib\nlocales_dir = pathlib.Path('src/Humanizer/Locales')\nfor f in locales_dir.rglob('*.yml'):\n    data = yaml.safe_load(f.read_text())\n    if isinstance(data, dict) and 'phrases' in data:\n        if not isinstance(data['phrases'], dict):\n            print(f'{f.name}: phrases must be a mapping, got {type(data[\"phrases\"]).__name__}')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Structure phrases as key-value pairs, never as a flat list.","Remove the phrases key if the locale has no phrase templates.","Validate indentation so phrase entries are mapping children, not sequence items."],"tags":["locale","yaml","source-generator","phrases","schema"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}