Humanizr/Humanizer · error · InvalidOperationException

Locale '{localeCode}.surfaces.number.parse' must be a mappin

Error message

Locale '{localeCode}.surfaces.number.parse' must be a mapping, not a scalar or sequence.

What it means

`surfaces.number.parse` holds the words-to-number parser description and must be a mapping (CanonicalLocaleAuthoring.cs:230-236).

Source

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

                    $"Locale '{localeCode}.surfaces.number' defines unsupported property '{property}'. Supported properties: words, parse, formatting.");
            }

            if (numberSurface.TryGetValue("words", out var wordsValue))
            {
                if (wordsValue is not SimpleYamlMapping wordsMapping)
                {
                    throw new InvalidOperationException(
                        $"Locale '{localeCode}.surfaces.number.words' must be a mapping, not a scalar or sequence.");
                }

                features["numberToWords"] = wordsMapping;
            }

            if (numberSurface.TryGetValue("parse", out var parseValue))
            {
                if (parseValue is not SimpleYamlMapping parseMapping)
                {
                    throw new InvalidOperationException(
                        $"Locale '{localeCode}.surfaces.number.parse' must be a mapping, not a scalar or sequence.");
                }

                features["wordsToNumber"] = parseMapping;
            }

            if (numberSurface.TryGetValue("formatting", out var fmtValue))
            {
                if (fmtValue is not SimpleYamlMapping fmtMapping)
                {
                    throw new InvalidOperationException(
                        $"Locale '{localeCode}.surfaces.number.formatting' must be a mapping, not a scalar or sequence.");
                }

                ValidateNumberFormattingBlock(localeCode, fmtMapping);
                features["numberFormatting"] = fmtMapping;
            }
        }

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Provide `parse:` as a mapping (engine + arguments).
  2. Omit parse if no parser override is needed.
  3. Rebuild.

Example fix

# before
surfaces:
  number:
    parse: english
# after
surfaces:
  number:
    parse:
      engine: "english"
Defensive patterns

Strategy: validation

Validate before calling

import yaml, sys
doc = yaml.safe_load(open(sys.argv[1], encoding='utf-8'))
p = ((doc.get('surfaces') or {}).get('number') or {}).get('parse')
if p is not None:
    assert isinstance(p, dict), 'surfaces.number.parse must be a mapping'

Prevention

When it happens

Trigger: Writing `parse: "english"` or a sequence under surfaces.number.

Common situations: Locale only needs spellout, so parse is given as a bare engine name by mistake.

Related errors


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