Humanizr/Humanizer · error · InvalidOperationException

Active inflection bundle must define lexemes.

Error message

Active inflection bundle must define lexemes.

What it means

A 'display-by-category' capability bundle must contain a 'lexemes' block sequence. ParseLexemes throws when the key is absent or when its value is not a YAML sequence. This is the missing-or-wrong-type branch (distinct from the empty-sequence branch).

Source

Thrown at src/Humanizer.SourceGenerators/Generators/ProfileCatalogs/InflectionCatalogParsing.cs:230

                regionalRulesValue is SimpleYamlMapping regionalRules &&
                regionalRules.Values.Any(entry =>
                    entry.Value is SimpleYamlScalar rule &&
                    CardinalRules.Contains(rule.Value) &&
                    ReachableCategories(rule.Value).Contains(category, StringComparer.Ordinal));
        }

        static ImmutableArray<InflectionLexemeInput> ParseLexemes(
            SimpleYamlMapping mapping,
            string cardinalRule,
            ImmutableHashSet<string> sourceIds,
            ImmutableArray<string> ownerScripts,
            string casing,
            bool allowEmpty)
        {
            if (!mapping.TryGetValue("lexemes", out var lexemeValue) ||
                lexemeValue is not SimpleYamlSequence lexemeSequence)
            {
                throw new InvalidOperationException("Active inflection bundle must define lexemes.");
            }

            if (lexemeSequence.Items.IsEmpty)
            {
                return allowEmpty
                    ? []
                    : throw new InvalidOperationException(
                        "Active inflection bundle must define lexemes.");
            }

            var ids = new HashSet<string>(StringComparer.Ordinal);
            var lexemes = ImmutableArray.CreateBuilder<InflectionLexemeInput>();
            foreach (var value in lexemeSequence.Items)
            {
                if (value is not SimpleYamlMapping lexeme)
                {
                    throw new InvalidOperationException("Inflection lexemes must be mappings.");
                }

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Add a 'lexemes:' block sequence with at least one lexeme mapping
  2. If the locale is intentionally empty, use 'capability: invariant'

Example fix

# before
  inflection:
    capability: 'display-by-category'
    # no lexemes key
# after
  inflection:
    capability: 'display-by-category'
    lexemes:
      - id: 'zz.noun.cat'
        pos: 'noun'
        countability: 'count'
        forms:
          singular:
            preferred: 'cat'
            accepted:
              - 'cat'
          dictionary-plural:
            preferred: 'cats'
            accepted:
              - 'cats'
          display:
            one:
              preferred: 'cat'
              accepted:
                - 'cat'
            other:
              preferred: 'cats'
              accepted:
                - 'cats'
        sources:
          - 'fixture'
Defensive patterns

Strategy: validation

Validate before calling

// Active (non-invariant) bundles require a lexemes block sequence:
if (capability == "display-by-category" &&
    (!m.TryGetValue("lexemes", out var lv) || lv is not SimpleYamlSequence))
    Report($"{locale}: display-by-category requires a 'lexemes' block sequence.");

Type guard

static bool HasLexemesSequence(SimpleYamlMapping m) =>
    m.TryGetValue("lexemes", out var v) && v is SimpleYamlSequence;

Prevention

When it happens

Trigger: 'surfaces.inflection' has 'capability: display-by-category' but no 'lexemes:' key, or 'lexemes:' is a scalar or mapping instead of a list.

Common situations: Starting a new active locale from the invariant fixture (which declares 'lexemes: []') and forgetting to add the key; a YAML indentation slip turning the sequence into a mapping.

Related errors


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