Humanizr/Humanizer · error · InvalidOperationException

Locale '{localeCode}.numberFormatting' must be a mapping.

Error message

Locale '{localeCode}.numberFormatting' must be a mapping.

What it means

The 'numberFormatting' feature holds locale-specific number format overrides (decimal separator, group separator, negative pattern, etc.) as a keyed mapping. A scalar or sequence node is structurally invalid and is rejected by the number-formatting resolver.

Source

Thrown at src/Humanizer.SourceGenerators/Common/LocaleYamlCatalog.cs:818

        static SimpleYamlMapping? ResolveCalendar(
            string localeCode,
            ImmutableDictionary<string, SimpleYamlValue> features)
        {
            return !features.TryGetValue("calendar", out var calendarValue)
                ? null
                : calendarValue as SimpleYamlMapping
                ?? throw new InvalidOperationException($"Locale '{localeCode}.calendar' must be a mapping.");
        }

        static SimpleYamlMapping? ResolveNumberFormatting(
            string localeCode,
            ImmutableDictionary<string, SimpleYamlValue> features)
        {
            return !features.TryGetValue("numberFormatting", out var formattingValue)
                ? null
                : formattingValue as SimpleYamlMapping
                ?? throw new InvalidOperationException($"Locale '{localeCode}.numberFormatting' must be a mapping.");
        }

        static SimpleYamlMapping? ResolveInflection(
            string localeCode,
            ImmutableDictionary<string, SimpleYamlValue> features)
        {
            return !features.TryGetValue("inflection", out var inflectionValue)
                ? null
                : inflectionValue as SimpleYamlMapping
                ?? throw new InvalidOperationException($"Locale '{localeCode}.inflection' must be a mapping.");
        }

        static ImmutableArray<string> ParseHeadingSequence(SimpleYamlMapping mapping, string key, string localeCode)
        {
            if (!mapping.TryGetValue(key, out var headingValue))
            {
                throw new InvalidOperationException($"Locale '{localeCode}.headings' must define '{key}'.");
            }

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Change the 'numberFormatting:' value to a mapping with the expected override keys.
  2. Remove the key if no overrides are needed.
  3. Reference an existing locale with numberFormatting overrides for the correct property names.

Example fix

# before
numberFormatting: 1.234,56

# after
numberFormatting:
  decimalSeparator: ","
  groupSeparator: "."
Defensive patterns

Strategy: validation

Validate before calling

import yaml, pathlib
locales_dir = pathlib.Path('src/Humanizer/Locales')
for f in locales_dir.rglob('*.yml'):
    data = yaml.safe_load(f.read_text())
    if isinstance(data, dict) and 'numberFormatting' in data:
        if not isinstance(data['numberFormatting'], dict):
            print(f'{f.name}: numberFormatting must be a mapping, got {type(data["numberFormatting"]).__name__}')

Prevention

When it happens

Trigger: A locale file sets 'numberFormatting:' to a scalar string or a sequence instead of a mapping of format properties.

Common situations: Authoring number format overrides incorrectly; indentation errors; copy-pasting from a source that used a different schema.

Related errors


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