Humanizr/Humanizer · error · InvalidOperationException

Feature '{featureName}' in locale '{localeCode}' must be a s

Error message

Feature '{featureName}' in locale '{localeCode}' must be a scalar or mapping.

What it means

Each supported feature key (formatter, ordinalizer, etc.) must resolve to either a YAML scalar (engine name shorthand) or a YAML mapping (full configuration). Any other YAML node type — typically a sequence — is structurally invalid for a feature value and the generator cannot interpret it.

Source

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

        static LocaleFeature? ResolveFeature(
            string localeCode,
            string featureName,
            ImmutableDictionary<string, SimpleYamlValue> features)
        {
            return !features.TryGetValue(featureName, out var featureValue)
                ? null
                : featureValue switch
                {
                    SimpleYamlScalar scalar => new LocaleFeature(
                        ownerLocaleCode: localeCode,
                        featureName: featureName,
                        kind: scalar.Value,
                        argument: null,
                        profileName: null,
                        profileRoot: default,
                        usesGeneratedProfile: false),
                    SimpleYamlMapping mapping => CreateMappedFeature(localeCode, featureName, mapping),
                    _ => throw new InvalidOperationException(
                        $"Feature '{featureName}' in locale '{localeCode}' must be a scalar or mapping.")
                };
        }

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

        static LocalePhraseCatalog? ResolvePhraseCatalog(
            string localeCode,
            ImmutableDictionary<string, SimpleYamlValue> features)
        {

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Check the feature named in the message and change its value from a sequence to a scalar string or a mapping (key-value pairs).
  2. Compare against a known-good locale file to see the expected shape for that feature name.
  3. Verify YAML indentation — a stray leading '-' can turn a mapping value into a sequence.

Example fix

# before
formatter:
  - default

# after
formatter: default
Defensive patterns

Strategy: validation

Validate before calling

# Validate that every feature value is a scalar or mapping, never a sequence.
# Use a YAML parser (e.g. PyYAML) and check node types:
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 not isinstance(data, dict):
        continue
    for key, val in data.items():
        if isinstance(val, list):
            print(f'{f.name}:{key} is a sequence but features must be scalar or mapping')

Prevention

When it happens

Trigger: A feature key in a locale YAML file is assigned a YAML sequence (list) value, e.g. 'formatter:\n - default'. The feature resolver's switch expression hits the default arm because the value is neither SimpleYamlScalar nor SimpleYamlMapping.

Common situations: Accidentally indenting a list under a feature key; copying a headings-style sequence into a scalar/mapping feature slot; YAML indentation drift placing list items under the wrong parent key.

Related errors


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