Humanizr/Humanizer · error · NotSupportedException

Culture '{Culture.Name}' does not apply grammatical case '{g

Error message

Culture '{Culture.Name}' does not apply grammatical case '{grammaticalCase}' to duration unit '{timeUnit}'.

What it means

Thrown when the requested grammatical case is supported by the locale, but for the specific TimeUnit the case-unit overlay is classified LocalizedDurationCaseUnitKind.NotApplicable. This is a finer-grained coverage gap: the locale supports the case in general, but that particular unit does not inflect for it (e.g. a locale where 'hour' has no distinct genitive form). NotSupportedException names both the case and the unit.

Source

Thrown at src/Humanizer/Localisation/Formatters/DefaultFormatter.cs:178

        }

        if (table.Classification == LocaleDurationCaseClassification.NotApplicable)
        {
            throw new NotSupportedException(
                $"Culture '{Culture.Name}' does not support grammatical-case duration phrases.");
        }

        if (!table.TryGetCase(grammaticalCase, out var caseOverlay))
        {
            throw new NotSupportedException(
                $"Culture '{Culture.Name}' does not support grammatical case '{grammaticalCase}' for duration phrases.");
        }

        var unitOverlay = caseOverlay.Units[(int)timeUnit];
        return unitOverlay.Kind switch
        {
            LocalizedDurationCaseUnitKind.SameAsNominative => FormatCaseAwareNominative(timeUnit, unit),
            LocalizedDurationCaseUnitKind.NotApplicable => throw new NotSupportedException(
                $"Culture '{Culture.Name}' does not apply grammatical case '{grammaticalCase}' to duration unit '{timeUnit}'."),
            LocalizedDurationCaseUnitKind.Unsupported => throw new NotSupportedException(
                $"Culture '{Culture.Name}' does not support grammatical case '{grammaticalCase}' for duration unit '{timeUnit}'."),
            _ => FormatCaseAwareTimeSpanPhrase(
                timeUnit,
                unit,
                unitOverlay.Phrase!.Value)
        };
    }

    /// <inheritdoc/>
    public virtual string TimeSpanHumanize_Age()
    {
        return phraseTable.TimeSpanAge ?? "{0}";
    }

    /// <inheritdoc/>
    public virtual string DataUnitHumanize(DataUnit dataUnit, double count, bool toSymbol = true)

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Per-unit fallback: when the case-aware call throws for a specific unit, fall back to the nominative form for that unit only.
  2. Catch NotSupportedException around each unit's case-aware call and use TimeSpanHumanize(timeUnit, unit) for the failing unit.
  3. If authoring locale data, mark the unit SameAsNominative instead of NotApplicable where the locale uses the nominative form.

Example fix

// before
foreach (var (unit, count) in parts)
    phrase += caseFormatter.TimeSpanHumanize(unit, count, grammaticalCase); // throws on one unit

// after
foreach (var (unit, count) in parts)
{
    try { phrase += caseFormatter.TimeSpanHumanize(unit, count, grammaticalCase); }
    catch (NotSupportedException) { phrase += formatter.TimeSpanHumanize(unit, count); }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Per-unit applicability is internal; the practical guard is a per-unit
// try/catch with nominative fallback for the offending unit.

Try / catch

foreach (var (unit, count) in parts)
{
    try { phrase += caseFormatter.TimeSpanHumanize(unit, count, gCase); }
    catch (NotSupportedException) { phrase += formatter.TimeSpanHumanize(unit, count); }
}

Prevention

When it happens

Trigger: Requesting a case for a TimeUnit whose overlay Kind is NotApplicable; mixing units where some inflect for the case and others do not; assuming uniform inflection across all units of a locale.

Common situations: Formatting compound durations ('2 hours 5 minutes') where minutes carry a genitive but hours do not (or vice versa) for the locale; reusing a single case across every TimeUnit in a loop; locale data that marks a unit as not-applicable pending verification.

Related errors


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