{"record":{"id":"3db6720023f81ec8","repo":"Humanizr/Humanizer","slug":"locale-localecode-headings-must-define-key","errorCode":null,"errorMessage":"Locale '{localeCode}.headings' must define '{key}'.","messagePattern":"Locale '(.+?)\\.headings' must define '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Humanizer.SourceGenerators/Common/LocaleYamlCatalog.cs","lineNumber":835,"sourceCode":"                : formattingValue as SimpleYamlMapping\n                ?? throw new InvalidOperationException($\"Locale '{localeCode}.numberFormatting' must be a mapping.\");\n        }\n\n        static SimpleYamlMapping? ResolveInflection(\n            string localeCode,\n            ImmutableDictionary<string, SimpleYamlValue> features)\n        {\n            return !features.TryGetValue(\"inflection\", out var inflectionValue)\n                ? null\n                : inflectionValue as SimpleYamlMapping\n                ?? throw new InvalidOperationException($\"Locale '{localeCode}.inflection' must be a mapping.\");\n        }\n\n        static ImmutableArray<string> ParseHeadingSequence(SimpleYamlMapping mapping, string key, string localeCode)\n        {\n            if (!mapping.TryGetValue(key, out var headingValue))\n            {\n                throw new InvalidOperationException($\"Locale '{localeCode}.headings' must define '{key}'.\");\n            }\n\n            if (headingValue is not SimpleYamlSequence sequence)\n            {\n                throw new InvalidOperationException($\"Locale '{localeCode}.headings.{key}' must be a sequence.\");\n            }\n\n            if (sequence.Items.Length != 16)\n            {\n                throw new InvalidOperationException($\"Locale '{localeCode}.headings.{key}' must contain exactly 16 entries.\");\n            }\n\n            var headings = ImmutableArray.CreateBuilder<string>(16);\n            for (var index = 0; index < sequence.Items.Length; index++)\n            {\n                if (sequence.Items[index] is not SimpleYamlScalar scalar)\n                {\n                    throw new InvalidOperationException($\"Locale '{localeCode}.headings.{key}[{index}]' must be a scalar.\");","sourceCodeStart":817,"sourceCodeEnd":853,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer.SourceGenerators/Common/LocaleYamlCatalog.cs#L817-L853","documentation":"The headings schema requires both 'full' and 'short' sub-keys. ParseHeadingSequence is called for each expected key, and if the key is absent from the mapping the generator cannot produce a complete heading set, so it fails fast.","triggerScenarios":"A locale's 'headings:' mapping defines 'full:' but omits 'short:', or vice versa. The {key} placeholder in the message names the missing property.","commonSituations":"Authoring partial heading data; copy-pasting from a locale that only had one variant; deleting a block during cleanup.","solutions":["Add the missing key named in the error message to the headings mapping.","Ensure both 'full:' and 'short:' are present, each with a 16-entry sequence.","If unsure of short forms, duplicate the full forms as a starting point and abbreviate afterward."],"exampleFix":"# before — missing 'short'\nheadings:\n  full:\n    - January\n\n# after\nheadings:\n  full:\n    - January\n  short:\n    - Jan","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 isinstance(data.get('headings'), dict):\n        for key in ('full', 'short'):\n            if key not in data['headings']:\n                print(f'{f.name}: headings must define \"{key}\"')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always provide both 'full' and 'short' under headings — neither is optional.","When adding headings for the first time, copy both blocks from a reference locale.","Add a lint that flags headings mappings missing either required key."],"tags":["locale","yaml","source-generator","headings","required-field"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}