Humanizr/Humanizer · error · InvalidOperationException

Distinct duration cases for '{localeCode}' must define at le

Error message

Distinct duration cases for '{localeCode}' must define at least one case.

What it means

Thrown by ParseLegacyForTests when classification is 'distinct', a 'cases' block is present, but after filtering out unsupported names and nominative, zero valid cases remain. Distinct classification requires at least one non-nominative grammatical case with authored data.

Source

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

            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}");
            }

            if (cases.Count == 0)
            {
                throw new InvalidOperationException($"Distinct duration cases for '{localeCode}' must define at least one case.");
            }

            return new DurationCaseCatalog(
                localeCode,
                classification,
                "nominative",
                ["nominative", .. cases.Keys.OrderBy(static name => name, StringComparer.Ordinal)],
                EmptyRealizations(),
                EmptySources(),
                cases.ToImmutable().Add("nominative", CreateBaseDurationOverlay()));
        }

        internal static DurationCaseCatalog ParseForTests(
            string localeCode,
            string text,
            string? casePluralRule = null,
            string? phrasesText = null)
        {

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Add at least one valid non-nominative case (e.g. genitive, dative, accusative) to the cases mapping.
  2. If the locale has no case distinctions, change classification from 'distinct' to 'same-as-nominative' or 'not-applicable'.
  3. Ensure the cases block is a non-empty YAML mapping with recognized case names.

Example fix

# before (only nominative, which is rejected)
durationCases:
  classification: distinct
  cases:
    nominative: { ... }
# after (at least one valid non-nominative case)
durationCases:
  classification: distinct
  cases:
    genitive: { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Distinct classification needs at least one valid non-nominative case
static bool DistinctHasAtLeastOneCase(SimpleYamlMapping durationCases,
    HashSet<string> supportedCases)
{
    if (durationCases.GetScalar("classification") != "distinct") return true;
    if (!durationCases.TryGetValue("cases", out var casesVal) || casesVal is not SimpleYamlMapping casesMap)
        return false;
    return casesMap.Values.Keys.Any(k => k != "nominative" && supportedCases.Contains(k));
}

Prevention

When it happens

Trigger: After iterating casesMapping keys for unsupported/nominative entries (error 56) and iterating known non-nominative cases present in the mapping, if cases.Count == 0 the throw fires. For example 'cases:\n nominative: { ... }' where nominative is rejected and no other valid case is present.

Common situations: A contributor writes a cases block containing only 'nominative' (which is rejected by error 56 logic) or only invalid names, leaving zero valid entries. Or the cases block is an empty mapping 'cases: {}'.

Related errors


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