{"record":{"id":"2641d8707c612891","repo":"Humanizr/Humanizer","slug":"locale-localecode-surfaces-number-defines-unsu","errorCode":null,"errorMessage":"Locale '{localeCode}.surfaces.number' defines unsupported property '{property}'. Supported properties: words, parse, formatting.","messagePattern":"Locale '(.+?)\\.surfaces\\.number' defines unsupported property '(.+?)'\\. Supported properties: words, parse, formatting\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs","lineNumber":215,"sourceCode":"                        features[\"inflection\"] = surfaceMapping;\n                        break;\n\n                    default:\n                        break;\n                }\n            }\n\n            return new LocaleDefinition(document.LocaleCode, document.VariantOf, features.ToImmutable());\n        }\n\n        static void AddNumberFeatures(\n            string localeCode,\n            SimpleYamlMapping numberSurface,\n            ImmutableDictionary<string, SimpleYamlValue>.Builder features)\n        {\n            foreach (var property in numberSurface.Values.Keys.Where(static property => property is not (\"words\" or \"parse\" or \"formatting\")))\n            {\n                throw new InvalidOperationException(\n                    $\"Locale '{localeCode}.surfaces.number' defines unsupported property '{property}'. Supported properties: words, parse, formatting.\");\n            }\n\n            if (numberSurface.TryGetValue(\"words\", out var wordsValue))\n            {\n                if (wordsValue is not SimpleYamlMapping wordsMapping)\n                {\n                    throw new InvalidOperationException(\n                        $\"Locale '{localeCode}.surfaces.number.words' must be a mapping, not a scalar or sequence.\");\n                }\n\n                features[\"numberToWords\"] = wordsMapping;\n            }\n\n            if (numberSurface.TryGetValue(\"parse\", out var parseValue))\n            {\n                if (parseValue is not SimpleYamlMapping parseMapping)\n                {","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs#L197-L233","documentation":"Under `surfaces.number:` only words, parse, and formatting are allowed (CanonicalLocaleAuthoring.cs:213-217). The number surface is deliberately split so writer and parser contracts stay aligned; legacy flat keys like numberToWords/wordsToNumber are not accepted here.","triggerScenarios":"Putting `numberToWords:` or `wordsToNumber:` directly under surfaces.number, or any typo (word:, parseing:).","commonSituations":"Migrating an old locale and leaving legacy number keys under the new number surface.","solutions":["Move spellout data under `number.words`, parser data under `number.parse`, decimal separators under `number.formatting`.","Remove any other property.","Rebuild."],"exampleFix":"# before\nsurfaces:\n  number:\n    numberToWords: {...}\n# after\nsurfaces:\n  number:\n    words: {...}","handlingStrategy":"validation","validationCode":"import yaml, sys\nALLOWED = {'words','parse','formatting'}\ndoc = yaml.safe_load(open(sys.argv[1], encoding='utf-8'))\nnum = (doc.get('surfaces') or {}).get('number')\nif isinstance(num, dict):\n    bad = [k for k in num if k not in ALLOWED]\n    assert not bad, f'unsupported surfaces.number keys: {bad}'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Author locales against the canonical schema; the error message lists the exact allowed names.","Run `dotnet build src/Humanizer/Humanizer.csproj` locally so the generator reports locale errors before push.","Copy an existing compliant locale file as your template rather than writing YAML from scratch."],"tags":["locale-authoring","yaml","source-generator","build","localization","schema","number"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}