Humanizr/Humanizer · error · InvalidOperationException

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

Error message

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

What it means

The 'calendar' feature carries locale-specific calendar overrides (month names, date separators, first day of week, etc.) as a keyed mapping. A scalar or sequence value cannot express those overrides, so the calendar resolver rejects non-mapping nodes.

Source

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

            foreach (var property in mapping.Values.Keys.Where(static property => property is not ("full" or "short")))
            {
                throw new InvalidOperationException(
                    $"Locale '{localeCode}.headings' defines unsupported property '{property}'. Supported properties: full, short.");
            }

            return new HeadingSet(
                ParseHeadingSequence(mapping, "full", localeCode),
                ParseHeadingSequence(mapping, "short", localeCode));
        }

        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

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Ensure the 'calendar:' value is a YAML mapping with valid override keys.
  2. If no calendar overrides are needed, remove the key entirely.
  3. Compare with a locale that has calendar overrides for the correct key set.

Example fix

# before
calendar: gregorian

# after
calendar:
  firstDayOfWeek: Monday
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 'calendar' in data:
        if not isinstance(data['calendar'], dict):
            print(f'{f.name}: calendar must be a mapping, got {type(data["calendar"]).__name__}')

Prevention

When it happens

Trigger: A locale file provides 'calendar:' as a scalar or sequence instead of a mapping of calendar property overrides.

Common situations: Misunderstanding the calendar schema; truncating a calendar block; indentation drift causing the mapping children to detach.

Related errors


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