Humanizr/Humanizer · error · InvalidOperationException

Distinct duration cases for '{localeCode}' must define 'case

Error message

Distinct duration cases for '{localeCode}' must define 'cases'.

What it means

Thrown by ParseLegacyForTests when classification is 'distinct' but the durationCases mapping has no 'cases' key. Distinct classification means the locale has different word forms per grammatical case, so at least the case definitions must be provided.

Source

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

                }

                return new DurationCaseCatalog(
                    localeCode,
                    classification,
                    "nominative",
                    classification == DurationCaseClassification.Invariant ? ["nominative"] : [],
                    EmptyRealizations(),
                    EmptySources(),
                    classification == DurationCaseClassification.Invariant
                        ? ImmutableDictionary<string, DurationCaseOverlay>.Empty
                            .WithComparers(StringComparer.Ordinal)
                            .Add("nominative", CreateBaseDurationOverlay())
                        : ImmutableDictionary<string, DurationCaseOverlay>.Empty.WithComparers(StringComparer.Ordinal));
            }

            if (!mapping.TryGetValue("cases", out var casesValue))
            {
                throw new InvalidOperationException($"Distinct duration cases for '{localeCode}' must define 'cases'.");
            }

            var casesMapping = ExpectMapping(casesValue, $"{path}.cases");
            var cases = ImmutableDictionary.CreateBuilder<string, DurationCaseOverlay>(StringComparer.Ordinal);
            foreach (var caseName in casesMapping.Values.Keys
                         .OrderBy(static name => name, StringComparer.Ordinal)
                         .Where(caseName => !Cases.Contains(caseName, StringComparer.Ordinal) || caseName == "nominative"))
            {
                throw new InvalidOperationException(
                    $"'{path}.cases' defines unsupported non-nominative case '{caseName}'.");
            }

            foreach (var caseName in Cases
                         .Where(static caseName => caseName != "nominative")
                         .Where(casesMapping.Values.ContainsKey))
            {
                cases[caseName] = ParseCase(casesMapping.Values[caseName], $"{path}.cases.{caseName}");
            }

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Add a 'cases' mapping with at least one non-nominative case definition (e.g. genitive, dative).
  2. If the locale doesn't actually have distinct cases, change classification to 'same-as-nominative', 'not-applicable', or 'unsupported'.
  3. Verify YAML indentation so 'cases' is a direct child of durationCases.

Example fix

# before (distinct but no cases)
durationCases:
  classification: distinct
# after
durationCases:
  classification: distinct
  cases:
    genitive: { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Distinct classification requires cases
static bool DistinctHasCases(SimpleYamlMapping durationCases)
{
    if (durationCases.GetScalar("classification") != "distinct") return true;
    return durationCases.TryGetValue("cases", out _);
}

Prevention

When it happens

Trigger: After the non-distinct early return, ParseLegacyForTests calls TryGetValue('cases'). If it returns false, the throw fires. For example 'classification: distinct' with no cases block underneath.

Common situations: A contributor sets classification to 'distinct' as a placeholder but hasn't yet authored the case data. Or the cases key is misspelled or indented wrong so the parser doesn't find it.

Related errors


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