Humanizr/Humanizer · critical · InvalidOperationException
Locale '{localeCode}.surfaces.number.formatting.{propertyNam
Error message
Locale '{localeCode}.surfaces.number.formatting.{propertyName}' must be a non-empty string. What it means
Thrown by ValidateOptionalFormattingProperty when decimalSeparator, negativeSign, or groupSeparator is a scalar string but empty. An empty separator is meaningless for number formatting and would corrupt output, so the canonical schema forbids it at build time.
Source
Thrown at src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs:396
}
}
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(
$"Locale '{localeCode}.surfaces.ordinal' defines unsupported property '{property}'. Supported properties: numeric, date, dateOnly.");
}
if (ordinalSurface.TryGetValue("numeric", out var numericValue))
{
if (numericValue is not SimpleYamlMapping numericMapping)View on GitHub (pinned to ffc2b77c0f)
Solutions
- Provide a concrete single-character value (e.g. 'groupSeparator: "."').
- If the locale should not override that separator, remove the property entirely rather than leaving it empty.
- Rebuild to confirm the formatting block is valid.
Example fix
# before
number:
formatting:
decimalSeparator:
# after
number:
formatting:
decimalSeparator: "," Defensive patterns
Strategy: validation
Validate before calling
# Detect empty formatting properties:
Select-String -Path src/Humanizer/Locales/<code>.yml -Pattern '(decimalSeparator|negativeSign|groupSeparator):\s*(""|\s*$)' Prevention
- Provide a concrete character for each separator you declare.
- Remove a separator property instead of leaving it empty when the locale should not override it.
- Build after edits to surface the offending {propertyName}.
When it happens
Trigger: A locale YAML writes 'decimalSeparator:' or 'groupSeparator: ""' with no value. ValidateOptionalFormattingProperty checks string.IsNullOrEmpty at CanonicalLocaleAuthoring.cs:394-398 and fails.
Common situations: Clearing a separator value while editing; a locale that intentionally omits grouping using an empty string instead of removing the key; copy-paste leaving blank values.
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/e009f886a6a014df.
Report an issue: GitHub.