Humanizr/Humanizer · error · InvalidOperationException

'{path}' must be a mapping.

Error message

'{path}' must be a mapping.

What it means

ExpectMapping (DurationCaseModels.cs:1198-1200) casts a parsed YAML node to SimpleYamlMapping and throws when the node is actually a scalar or a sequence. Duration-case parsing requires mappings at the case, units, and unit levels; any node that collapsed to a scalar/list (often a YAML indentation error) fails here.

Source

Thrown at src/Humanizer.SourceGenerators/Common/DurationCaseModels.cs:1200

                throw new InvalidOperationException(
                    $"Case overlay '{path}' must explicitly define singular and numeric multiple forms.");
            }

            return new DurationCaseUnit(DurationCaseUnitKind.Phrase, phrase);
        }

        static bool ContainsInheritanceMarker(SimpleYamlValue value) =>
            value switch
            {
                SimpleYamlScalar scalar => scalar.Value.Contains("↑↑↑", StringComparison.Ordinal),
                SimpleYamlMapping mapping => mapping.Values.Values.Any(ContainsInheritanceMarker),
                SimpleYamlSequence sequence => sequence.Items.Any(ContainsInheritanceMarker),
                _ => false
            };

        static SimpleYamlMapping ExpectMapping(SimpleYamlValue value, string path) =>
            value as SimpleYamlMapping
            ?? throw new InvalidOperationException($"'{path}' must be a mapping.");

        static void RejectUnknownKeys(SimpleYamlMapping mapping, string path, IReadOnlyCollection<string> supported)
        {
            foreach (var key in mapping.Values.Keys.Where(key => !supported.Contains(key)))
            {
                throw new InvalidOperationException(
                    $"'{path}' defines unsupported property '{key}'. Supported properties: {string.Join(", ", supported)}.");
            }
        }
    }
}

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Fix the YAML so the node is a mapping (indented 'key: value' pairs).
  2. Check indentation against a known-good locale (e.g. src/Humanizer/Locales/cs.yml) at the same structural level.
  3. Validate the file with a YAML linter before building.

Example fix

# before - units is a scalar, not a mapping
cases:
  genitive: second
# after
cases:
  genitive:
    units:
      second:
        sameAsNominative: true
Defensive patterns

Strategy: validation

Validate before calling

# Validate that case/units/unit nodes are mappings before building
function Assert-IsMapping($node, $path) {
    if ($null -eq $node -or -not ($node -is [hashtable])) {
        throw "'$path' must be a YAML mapping (key: value), got $(($node | Out-String).Trim())"
    }
}
Assert-IsMapping $parsed.durationCases.cases.$case "$locale.cases.$case"
Assert-IsMapping $parsed.durationCases.cases.$case.units "$locale.cases.$case.units"

Prevention

When it happens

Trigger: A YAML node expected to be key:value is a bare scalar or a dash list — e.g. 'units: second' instead of 'units: { second: {...} }', or a unit value that is a plain string.

Common situations: YAML indentation/typo that flattens a mapping into a scalar; using a '-' sequence where a ':' mapping is required; missing colon after a key.

Related errors


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