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

  1. Provide a concrete single-character value (e.g. 'groupSeparator: "."').
  2. If the locale should not override that separator, remove the property entirely rather than leaving it empty.
  3. 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

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


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