Humanizr/Humanizer · critical · InvalidOperationException
Locale '{localeCode}.surfaces.number.formatting.{propertyNam
Error message
Locale '{localeCode}.surfaces.number.formatting.{propertyName}' must be a scalar string, not a mapping or sequence. What it means
Thrown by ValidateOptionalFormattingProperty when a property under surfaces.number.formatting (decimalSeparator, negativeSign, or groupSeparator) is present but is not a scalar — it is a YAML mapping or sequence. These three values are single characters/strings, so structured values are rejected at build time.
Source
Thrown at src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs:390
ValidateOptionalFormattingProperty(localeCode, formatting, "groupSeparator");
if (formatting.Values.Count == 0)
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.number.formatting' must define at least one property.");
}
}
static void ValidateOptionalFormattingProperty(string localeCode, SimpleYamlMapping formatting, string propertyName)
{
if (!formatting.TryGetValue(propertyName, out var value))
{
return;
}
if (value is not SimpleYamlScalar scalar)
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.number.formatting.{propertyName}' must be a scalar string, not a mapping or sequence.");
}
if (string.IsNullOrEmpty(scalar.Value))
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.number.formatting.{propertyName}' must be a non-empty string.");
}
}
static void AddOrdinalFeatures(
string localeCode,
SimpleYamlMapping ordinalSurface,
ImmutableDictionary<string, SimpleYamlValue>.Builder features)
{
foreach (var property in ordinalSurface.Values.Keys.Where(static property => property is not ("numeric" or "date" or "dateOnly")))
{
throw new InvalidOperationException(View on GitHub (pinned to ffc2b77c0f)
Solutions
- Rewrite the property as a single inline string scalar, e.g. 'decimalSeparator: ","'.
- Verify YAML indentation so the value sits on the same line as the key.
- Rebuild to confirm ValidateOptionalFormattingProperty passes.
Example fix
# before
number:
formatting:
decimalSeparator:
value: ","
# after
number:
formatting:
decimalSeparator: "," Defensive patterns
Strategy: validation
Validate before calling
# Ensure formatting properties are inline scalars: # 'decimalSeparator: ","' rather than nested mappings. # YAML lint: each of the three keys, if present, must have a scalar value.
Prevention
- Write separators as single inline string values.
- Avoid pasting CLDR nested symbol objects into the formatting block.
- Build after edits to get the precise {propertyName} that failed.
When it happens
Trigger: A locale YAML writes 'decimalSeparator:\n value: ","' (nested mapping) or a list form for one of the three formatting properties. The type check at CanonicalLocaleAuthoring.cs:386-392 fails because the value is not a SimpleYamlScalar.
Common situations: Pasting CLDR nested symbol objects; mis-indenting so the value becomes a child mapping; converting from a JSON config that wrapped symbols in objects.
Related errors
- Locale '{localeCode}.surfaces.number.formatting' defines uns
- Locale '{localeCode}.surfaces.number.formatting' must define
- Locale '{localeCode}.surfaces.number.formatting.{propertyNam
- Locale '{localeCode}.{path}' defines duplicate numeric minut
- Locale '{localeCode}.{path}.{key}' must be a string.
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/ab17e7d4b7933dc2.
Report an issue: GitHub.