Humanizr/Humanizer · error · NotSupportedException
The configured ITimeSpanHumanizeStrategy does not support gr
Error message
The configured ITimeSpanHumanizeStrategy does not support grammatical-case-aware durations.
What it means
Thrown by HumanizeWithCase when the configured ITimeSpanHumanizeStrategy (set via Configurator.TimeSpanHumanizeStrategy) does not also implement IGrammaticalCaseTimeSpanHumanizeStrategy. Grammatical-case-aware duration output requires the strategy to support case selection, which is an opt-in interface beyond the base ITimeSpanHumanizeStrategy.
Source
Thrown at src/Humanizer/TimeSpanHumanizeExtensions.cs:118
/// <param name="collectionSeparator">The separator used to combine time parts. If null, the culture's default collection formatter is used.</param>
/// <returns>The locale-authored unit-case phrase. The count may be written explicitly or encoded by the unit form.</returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="grammaticalCase"/> is not defined.</exception>
/// <exception cref="NotSupportedException">The configured strategy, selected formatter, locale, or duration unit does not support the requested case.</exception>
public static string HumanizeWithCase(
this TimeSpan timeSpan,
GrammaticalCase grammaticalCase,
int precision,
bool countEmptyUnits,
CultureInfo? culture = null,
TimeUnit maxUnit = TimeUnit.Week,
TimeUnit minUnit = TimeUnit.Millisecond,
string? collectionSeparator = ", ")
{
ValidateGrammaticalCase(grammaticalCase);
if (Configurator.TimeSpanHumanizeStrategy is not IGrammaticalCaseTimeSpanHumanizeStrategy strategy)
{
throw new NotSupportedException(
$"The configured {nameof(ITimeSpanHumanizeStrategy)} does not support grammatical-case-aware durations.");
}
return strategy.Humanize(
timeSpan,
precision,
countEmptyUnits,
culture,
maxUnit,
minUnit,
collectionSeparator,
false,
grammaticalCase);
}
/// <summary>
/// Turns a <see cref="TimeSpan"/> into a human readable form using localized unit symbols.
/// </summary>View on GitHub (pinned to ffc2b77c0f)
Solutions
- Make your custom strategy implement IGrammaticalCaseTimeSpanHumanizeStrategy.
- Restore the default strategy (DefaultTimeSpanHumanizeStrategy) which supports cases.
- Avoid calling HumanizeWithCase when using a strategy that doesn't support it.
Example fix
// before
public class MyStrategy : ITimeSpanHumanizeStrategy
{
public string Humanize(TimeSpan ts, int p, bool c, CultureInfo? cult, TimeUnit max, TimeUnit min, string? sep, bool words, bool symbols) => ...
}
// after
public class MyStrategy : ITimeSpanHumanizeStrategy, IGrammaticalCaseTimeSpanHumanizeStrategy
{
public string Humanize(TimeSpan ts, int p, bool c, CultureInfo? cult, TimeUnit max, TimeUnit min, string? sep, bool words, bool symbols) => ...
public string Humanize(TimeSpan ts, int p, bool c, CultureInfo? cult, TimeUnit max, TimeUnit min, string? sep, bool symbols, GrammaticalCase gc) => ...
} Defensive patterns
Strategy: type-guard
Validate before calling
static bool StrategySupportsCase(ITimeSpanHumanizeStrategy strategy) =>
strategy is IGrammaticalCaseTimeSpanHumanizeStrategy; Type guard
static bool CanHumanizeWithCase(ITimeSpanHumanizeStrategy strategy) =>
strategy is IGrammaticalCaseTimeSpanHumanizeStrategy; Prevention
- Implement IGrammaticalCaseTimeSpanHumanizeStrategy on all custom strategies.
- Check Configurator.TimeSpanHumanizeStrategy type before calling HumanizeWithCase.
- Document interface requirements for custom strategies.
When it happens
Trigger: Registering a custom ITimeSpanHumanizeStrategy via Configurator.TimeSpanHumanizeStrategy and then calling timeSpan.HumanizeWithCase(GrammaticalCase.Genitive). The check at line 116 tests the type and throws.
Common situations: Replacing the default strategy with a custom implementation for logging, caching, or experimentation, without implementing the case-aware interface. Upgrading Humanizer and discovering new case APIs that the old custom strategy doesn't support.
Related errors
- Custom strategy type '{GetType().FullName}' must explicitly
- Grammatical case is not supported for time-unit symbols.
- The formatter for '{culture?.Name ?? CultureInfo.CurrentCult
- Custom formatter type '{GetType().FullName}' must explicitly
- Culture '{Culture.Name}' has no grammatical-case classificat
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/d549051c80ef6324.
Report an issue: GitHub.