Humanizr/Humanizer · error · InvalidOperationException
Locale '{localeCode}.surfaces.number' defines unsupported pr
Error message
Locale '{localeCode}.surfaces.number' defines unsupported property '{property}'. Supported properties: words, parse, formatting. What it means
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.
Source
Thrown at src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs:215
features["inflection"] = surfaceMapping;
break;
default:
break;
}
}
return new LocaleDefinition(document.LocaleCode, document.VariantOf, features.ToImmutable());
}
static void AddNumberFeatures(
string localeCode,
SimpleYamlMapping numberSurface,
ImmutableDictionary<string, SimpleYamlValue>.Builder features)
{
foreach (var property in numberSurface.Values.Keys.Where(static property => property is not ("words" or "parse" or "formatting")))
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.number' defines unsupported property '{property}'. Supported properties: words, parse, formatting.");
}
if (numberSurface.TryGetValue("words", out var wordsValue))
{
if (wordsValue is not SimpleYamlMapping wordsMapping)
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.number.words' must be a mapping, not a scalar or sequence.");
}
features["numberToWords"] = wordsMapping;
}
if (numberSurface.TryGetValue("parse", out var parseValue))
{
if (parseValue is not SimpleYamlMapping parseMapping)
{View on GitHub (pinned to ffc2b77c0f)
Solutions
- Move spellout data under `number.words`, parser data under `number.parse`, decimal separators under `number.formatting`.
- Remove any other property.
- Rebuild.
Example fix
# before
surfaces:
number:
numberToWords: {...}
# after
surfaces:
number:
words: {...} Defensive patterns
Strategy: validation
Validate before calling
import yaml, sys
ALLOWED = {'words','parse','formatting'}
doc = yaml.safe_load(open(sys.argv[1], encoding='utf-8'))
num = (doc.get('surfaces') or {}).get('number')
if isinstance(num, dict):
bad = [k for k in num if k not in ALLOWED]
assert not bad, f'unsupported surfaces.number keys: {bad}' Prevention
- 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.
When it happens
Trigger: Putting `numberToWords:` or `wordsToNumber:` directly under surfaces.number, or any typo (word:, parseing:).
Common situations: Migrating an old locale and leaving legacy number keys under the new number surface.
Related errors
- Locale '{localeCode}' defines unsupported top-level property
- Locale '{localeCode}.surfaces' defines unsupported surface '
- Locale '{localeCode}.surfaces.number.words' must be a mappin
- Locale '{localeCode}.surfaces.number.parse' must be a mappin
- Locale '{localeCode}.surfaces.number.formatting' must be a m
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/2641d8707c612891.
Report an issue: GitHub.