{"record":{"id":"d549051c80ef6324","repo":"Humanizr/Humanizer","slug":"the-configured-itimespanhumanizestrategy-does-not","errorCode":null,"errorMessage":"The configured ITimeSpanHumanizeStrategy does not support grammatical-case-aware durations.","messagePattern":"The configured ITimeSpanHumanizeStrategy does not support grammatical-case-aware durations\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Humanizer/TimeSpanHumanizeExtensions.cs","lineNumber":118,"sourceCode":"    /// <param name=\"collectionSeparator\">The separator used to combine time parts. If null, the culture's default collection formatter is used.</param>\n    /// <returns>The locale-authored unit-case phrase. The count may be written explicitly or encoded by the unit form.</returns>\n    /// <exception cref=\"ArgumentOutOfRangeException\"><paramref name=\"grammaticalCase\"/> is not defined.</exception>\n    /// <exception cref=\"NotSupportedException\">The configured strategy, selected formatter, locale, or duration unit does not support the requested case.</exception>\n    public static string HumanizeWithCase(\n        this TimeSpan timeSpan,\n        GrammaticalCase grammaticalCase,\n        int precision,\n        bool countEmptyUnits,\n        CultureInfo? culture = null,\n        TimeUnit maxUnit = TimeUnit.Week,\n        TimeUnit minUnit = TimeUnit.Millisecond,\n        string? collectionSeparator = \", \")\n    {\n        ValidateGrammaticalCase(grammaticalCase);\n\n        if (Configurator.TimeSpanHumanizeStrategy is not IGrammaticalCaseTimeSpanHumanizeStrategy strategy)\n        {\n            throw new NotSupportedException(\n                $\"The configured {nameof(ITimeSpanHumanizeStrategy)} does not support grammatical-case-aware durations.\");\n        }\n\n        return strategy.Humanize(\n            timeSpan,\n            precision,\n            countEmptyUnits,\n            culture,\n            maxUnit,\n            minUnit,\n            collectionSeparator,\n            false,\n            grammaticalCase);\n    }\n\n    /// <summary>\n    /// Turns a <see cref=\"TimeSpan\"/> into a human readable form using localized unit symbols.\n    /// </summary>","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer/TimeSpanHumanizeExtensions.cs#L100-L136","documentation":"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.","triggerScenarios":"Registering a custom ITimeSpanHumanizeStrategy via Configurator.TimeSpanHumanizeStrategy and then calling timeSpan.HumanizeWithCase(GrammaticalCase.Genitive). The check at line 116 tests the type and throws.","commonSituations":"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.","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."],"exampleFix":"// before\npublic class MyStrategy : ITimeSpanHumanizeStrategy\n{\n    public string Humanize(TimeSpan ts, int p, bool c, CultureInfo? cult, TimeUnit max, TimeUnit min, string? sep, bool words, bool symbols) => ...\n}\n\n// after\npublic class MyStrategy : ITimeSpanHumanizeStrategy, IGrammaticalCaseTimeSpanHumanizeStrategy\n{\n    public string Humanize(TimeSpan ts, int p, bool c, CultureInfo? cult, TimeUnit max, TimeUnit min, string? sep, bool words, bool symbols) => ...\n    public string Humanize(TimeSpan ts, int p, bool c, CultureInfo? cult, TimeUnit max, TimeUnit min, string? sep, bool symbols, GrammaticalCase gc) => ...\n}","handlingStrategy":"type-guard","validationCode":"static bool StrategySupportsCase(ITimeSpanHumanizeStrategy strategy) =>\n    strategy is IGrammaticalCaseTimeSpanHumanizeStrategy;","typeGuard":"static bool CanHumanizeWithCase(ITimeSpanHumanizeStrategy strategy) =>\n    strategy is IGrammaticalCaseTimeSpanHumanizeStrategy;","tryCatchPattern":null,"preventionTips":["Implement IGrammaticalCaseTimeSpanHumanizeStrategy on all custom strategies.","Check Configurator.TimeSpanHumanizeStrategy type before calling HumanizeWithCase.","Document interface requirements for custom strategies."],"tags":["timespan","grammatical-case","custom-provider","not-supported"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}