Humanizr/Humanizer · error · InvalidOperationException

Inflection rules must be a block sequence.

Error message

Inflection rules must be a block sequence.

What it means

The optional 'rules:' key, when present, must be a YAML block sequence (a list of rule mappings). ParseRules throws when 'rules:' exists but is a scalar or mapping rather than a sequence.

Source

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

            return new(preferred, accepted);
        }

        static ImmutableArray<InflectionRuleInput> ParseRules(
            SimpleYamlMapping mapping,
            ImmutableHashSet<string> sourceIds,
            ImmutableHashSet<string> lexemeIds,
            ImmutableArray<string> ownerScripts,
            string cardinalRule,
            string casing)
        {
            if (!mapping.TryGetValue("rules", out var value))
            {
                return [];
            }

            if (value is not SimpleYamlSequence sequence)
            {
                throw new InvalidOperationException("Inflection rules must be a block sequence.");
            }

            var rules = ImmutableArray.CreateBuilder<InflectionRuleInput>();
            var ids = new HashSet<string>(StringComparer.Ordinal);
            foreach (var item in sequence.Items)
            {
                if (item is not SimpleYamlMapping rule)
                {
                    throw new InvalidOperationException("Inflection rules must be mappings.");
                }

                ValidateProperties(
                    rule,
                    "Inflection rule",
                    "id", "direction", "priority", "scope", "match", "output",
                    "hostileExclusions", "hostile-exclusions", "reverse", "sources");
                var id = GetRequiredScalar(rule, "id", "Inflection rule must define id");
                if (!ids.Add(id))

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Make 'rules:' a block sequence whose items are mappings
  2. Omit 'rules:' entirely if no productive rules are needed

Example fix

# before
    rules:
      id: 'zz.forward.consonant-y'
      direction: 'forward'
# after
    rules:
      - id: 'zz.forward.consonant-y'
        direction: 'forward'
        ...
Defensive patterns

Strategy: validation

Validate before calling

if (m.TryGetValue("rules", out var rv) && rv is not SimpleYamlSequence)
    Report($"{locale}: 'rules' must be a block sequence.");

Type guard

static bool RulesIsSequence(SimpleYamlMapping m) =>
    !m.TryGetValue("rules", out var v) || v is SimpleYamlSequence;

Prevention

When it happens

Trigger: 'rules:' is present but is a mapping or scalar rather than a list.

Common situations: Indenting rule content as a mapping instead of a sequence; pasting a single rule object directly under 'rules:' without the leading dash.

Related errors


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