Humanizr/Humanizer · error · InvalidOperationException
Locale '{localeCode}.surfaces.number.formatting' must be a m
Error message
Locale '{localeCode}.surfaces.number.formatting' must be a mapping, not a scalar or sequence. What it means
`surfaces.number.formatting` must be a mapping of decimalSeparator/negativeSign/groupSeparator (CanonicalLocaleAuthoring.cs:241-247) before its contents are validated by ValidateNumberFormattingBlock.
Source
Thrown at src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs:245
features["numberToWords"] = wordsMapping;
}
if (numberSurface.TryGetValue("parse", out var parseValue))
{
if (parseValue is not SimpleYamlMapping parseMapping)
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.number.parse' must be a mapping, not a scalar or sequence.");
}
features["wordsToNumber"] = parseMapping;
}
if (numberSurface.TryGetValue("formatting", out var fmtValue))
{
if (fmtValue is not SimpleYamlMapping fmtMapping)
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.number.formatting' must be a mapping, not a scalar or sequence.");
}
ValidateNumberFormattingBlock(localeCode, fmtMapping);
features["numberFormatting"] = fmtMapping;
}
}
static SimpleYamlMapping NormalizeClockSurface(string localeCode, SimpleYamlMapping clockSurface)
{
if (clockSurface.DuplicateKeys.Contains("minuteWordsMap"))
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.clock.minuteWordsMap' defines duplicate entries; choose either the dense or sparse form.");
}
if (!clockSurface.TryGetValue("minuteWordsMap", out var minuteWordsMap))
{View on GitHub (pinned to ffc2b77c0f)
Solutions
- Use a mapping: `formatting:` then `decimalSeparator: ","`.
- Provide at least one of the three allowed keys (a later check requires >=1).
- Rebuild.
Example fix
# before
surfaces:
number:
formatting: ","
# after
surfaces:
number:
formatting:
decimalSeparator: "," Defensive patterns
Strategy: validation
Validate before calling
import yaml, sys
doc = yaml.safe_load(open(sys.argv[1], encoding='utf-8'))
f = ((doc.get('surfaces') or {}).get('number') or {}).get('formatting')
if f is not None:
assert isinstance(f, dict), 'surfaces.number.formatting must be a mapping' 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: Writing `formatting: ","` or a list under surfaces.number.
Common situations: Trying to set just a decimal separator as a scalar.
Related errors
- Locale '{localeCode}.surfaces.number' defines unsupported pr
- Locale '{localeCode}.surfaces.number.words' must be a mappin
- Locale '{localeCode}.surfaces.number.parse' must be a mappin
- Locale '{localeCode}' defines unsupported top-level property
- Locale '{localeCode}' must define required top-level propert
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/70def03a7a913c93.
Report an issue: GitHub.