Humanizr/Humanizer · critical · InvalidOperationException

Locale '{localeCode}.surfaces.number.formatting' defines uns

Error message

Locale '{localeCode}.surfaces.number.formatting' defines unsupported property '{property}'. Supported properties: decimalSeparator, negativeSign, groupSeparator.

What it means

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.

Source

Thrown at src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs:366

        {
            if (value is not SimpleYamlScalar scalar || !scalar.IsString)
            {
                throw new InvalidOperationException(
                    $"Locale '{localeCode}.{path}.{key}' must be a string.");
            }

            if (!allowEmpty && string.IsNullOrEmpty(scalar.Value))
            {
                throw new InvalidOperationException(
                    $"Locale '{localeCode}.{path}.{key}' must be a non-empty string. Omit unused sparse slots instead.");
            }
        }

        static void ValidateNumberFormattingBlock(string localeCode, SimpleYamlMapping formatting)
        {
            foreach (var property in formatting.Values.Keys.Where(static property => property is not ("decimalSeparator" or "negativeSign" or "groupSeparator")))
            {
                throw new InvalidOperationException(
                    $"Locale '{localeCode}.surfaces.number.formatting' defines unsupported property '{property}'. Supported properties: decimalSeparator, negativeSign, groupSeparator.");
            }

            ValidateOptionalFormattingProperty(localeCode, formatting, "decimalSeparator");
            ValidateOptionalFormattingProperty(localeCode, formatting, "negativeSign");
            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))
            {

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Remove the unsupported property '{property}' from surfaces.number.formatting.
  2. If you need a real new formatting dimension, extend SupportedSurfaceNames/ValidateNumberFormattingBlock in the source generator rather than smuggling it into YAML.
  3. Confirm only decimalSeparator, negativeSign, and/or groupSeparator remain, then rebuild.

Example fix

# before
number:
  formatting:
    decimalSeparator: ","
    thousandsSeparator: "."   # unsupported
# after
number:
  formatting:
    decimalSeparator: ","
    groupSeparator: "."
Defensive patterns

Strategy: validation

Validate before calling

# Validate the number.formatting keys against the allow-list before building.
$allowed = 'decimalSeparator','negativeSign','groupSeparator'
$yaml = Get-Content src/Humanizer/Locales/<code>.yml -Raw
# (Parse with any YAML module) and assert every key under number.formatting is in $allowed.

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13). Data as JSON: /api/errors/e7694b4d7b05518e. Report an issue: GitHub.