{"record":{"id":"e7694b4d7b05518e","repo":"Humanizr/Humanizer","slug":"locale-localecode-surfaces-number-formatting-d","errorCode":null,"errorMessage":"Locale '{localeCode}.surfaces.number.formatting' defines unsupported property '{property}'. Supported properties: decimalSeparator, negativeSign, groupSeparator.","messagePattern":"Locale '(.+?)\\.surfaces\\.number\\.formatting' defines unsupported property '(.+?)'\\. Supported properties: decimalSeparator, negativeSign, groupSeparator\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs","lineNumber":366,"sourceCode":"        {\n            if (value is not SimpleYamlScalar scalar || !scalar.IsString)\n            {\n                throw new InvalidOperationException(\n                    $\"Locale '{localeCode}.{path}.{key}' must be a string.\");\n            }\n\n            if (!allowEmpty && string.IsNullOrEmpty(scalar.Value))\n            {\n                throw new InvalidOperationException(\n                    $\"Locale '{localeCode}.{path}.{key}' must be a non-empty string. Omit unused sparse slots instead.\");\n            }\n        }\n\n        static void ValidateNumberFormattingBlock(string localeCode, SimpleYamlMapping formatting)\n        {\n            foreach (var property in formatting.Values.Keys.Where(static property => property is not (\"decimalSeparator\" or \"negativeSign\" or \"groupSeparator\")))\n            {\n                throw new InvalidOperationException(\n                    $\"Locale '{localeCode}.surfaces.number.formatting' defines unsupported property '{property}'. Supported properties: decimalSeparator, negativeSign, groupSeparator.\");\n            }\n\n            ValidateOptionalFormattingProperty(localeCode, formatting, \"decimalSeparator\");\n            ValidateOptionalFormattingProperty(localeCode, formatting, \"negativeSign\");\n            ValidateOptionalFormattingProperty(localeCode, formatting, \"groupSeparator\");\n\n            if (formatting.Values.Count == 0)\n            {\n                throw new InvalidOperationException(\n                    $\"Locale '{localeCode}.surfaces.number.formatting' must define at least one property.\");\n            }\n        }\n\n        static void ValidateOptionalFormattingProperty(string localeCode, SimpleYamlMapping formatting, string propertyName)\n        {\n            if (!formatting.TryGetValue(propertyName, out var value))\n            {","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs#L348-L384","documentation":"Thrown by ValidateNumberFormattingBlock when surfaces.number.formatting in a locale YAML contains a property other than the three allowed keys: decimalSeparator, negativeSign, groupSeparator. The canonical schema is closed, so any extra key (including renamed or locale-specific ones) is rejected at build time to keep formatting behavior predictable.","triggerScenarios":"A contributor adds a property like 'percentSign', 'currencySymbol', or 'thousandsSeparator' under surfaces.number.formatting. The loop at CanonicalLocaleAuthoring.cs:364-369 flags any key not in the allow-list and throws.","commonSituations":"Porting from ICU/CLDR data that includes extra number symbols; renaming 'groupSeparator' to the older 'thousandsSeparator'; pasting a formatting block from another library's config.","solutions":["Remove the unsupported property '{property}' from surfaces.number.formatting.","If you need a real new formatting dimension, extend SupportedSurfaceNames/ValidateNumberFormattingBlock in the source generator rather than smuggling it into YAML.","Confirm only decimalSeparator, negativeSign, and/or groupSeparator remain, then rebuild."],"exampleFix":"# before\nnumber:\n  formatting:\n    decimalSeparator: \",\"\n    thousandsSeparator: \".\"   # unsupported\n# after\nnumber:\n  formatting:\n    decimalSeparator: \",\"\n    groupSeparator: \".\"","handlingStrategy":"validation","validationCode":"# Validate the number.formatting keys against the allow-list before building.\n$allowed = 'decimalSeparator','negativeSign','groupSeparator'\n$yaml = Get-Content src/Humanizer/Locales/<code>.yml -Raw\n# (Parse with any YAML module) and assert every key under number.formatting is in $allowed.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember the formatting surface is closed: only decimalSeparator, negativeSign, groupSeparator.","Use 'groupSeparator', not the legacy 'thousandsSeparator'.","If a new formatting dimension is needed, extend ValidateNumberFormattingBlock in the generator first."],"tags":["localization","yaml","source-generator","locale","build","number-formatting"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}