{"record":{"id":"16b3503211de65cf","repo":"Humanizr/Humanizer","slug":"culture-culture-name-does-not-support-grammati-16b350","errorCode":null,"errorMessage":"Culture '{Culture.Name}' does not support grammatical case '{grammaticalCase}' for duration unit '{timeUnit}'.","messagePattern":"Culture '(.+?)' does not support grammatical case '(.+?)' for duration unit '(.+?)'\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Humanizer/Localisation/Formatters/DefaultFormatter.cs","lineNumber":180,"sourceCode":"        if (table.Classification == LocaleDurationCaseClassification.NotApplicable)\n        {\n            throw new NotSupportedException(\n                $\"Culture '{Culture.Name}' does not support grammatical-case duration phrases.\");\n        }\n\n        if (!table.TryGetCase(grammaticalCase, out var caseOverlay))\n        {\n            throw new NotSupportedException(\n                $\"Culture '{Culture.Name}' does not support grammatical case '{grammaticalCase}' for duration phrases.\");\n        }\n\n        var unitOverlay = caseOverlay.Units[(int)timeUnit];\n        return unitOverlay.Kind switch\n        {\n            LocalizedDurationCaseUnitKind.SameAsNominative => FormatCaseAwareNominative(timeUnit, unit),\n            LocalizedDurationCaseUnitKind.NotApplicable => throw new NotSupportedException(\n                $\"Culture '{Culture.Name}' does not apply grammatical case '{grammaticalCase}' to duration unit '{timeUnit}'.\"),\n            LocalizedDurationCaseUnitKind.Unsupported => throw new NotSupportedException(\n                $\"Culture '{Culture.Name}' does not support grammatical case '{grammaticalCase}' for duration unit '{timeUnit}'.\"),\n            _ => FormatCaseAwareTimeSpanPhrase(\n                timeUnit,\n                unit,\n                unitOverlay.Phrase!.Value)\n        };\n    }\n\n    /// <inheritdoc/>\n    public virtual string TimeSpanHumanize_Age()\n    {\n        return phraseTable.TimeSpanAge ?? \"{0}\";\n    }\n\n    /// <inheritdoc/>\n    public virtual string DataUnitHumanize(DataUnit dataUnit, double count, bool toSymbol = true)\n    {\n        if (TryFormatDataUnitFromPhraseTable(dataUnit, count, toSymbol, out var generated))","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs#L162-L198","documentation":"Thrown when a locale's duration case table marks a specific TimeUnit as Unsupported for the requested GrammaticalCase. This is a per-unit limitation: the culture supports the case in general (the earlier TryGetCase check passed), but this particular unit (e.g. Millisecond) has no case-inflected form. Reached only through the case-aware TimeSpanHumanize overloads that route into IGrammaticalCaseTimeSpanFormatter.TimeSpanHumanize.","triggerScenarios":"Calling timeSpan.Humanize(..., grammaticalCase: GrammaticalCase.Instrumental) or the 3-arg Humanize(TimeSpan, GrammaticalCase) for a locale whose LocaleDurationCaseTable has Units[(int)timeUnit].Kind == LocalizedDurationCaseUnitKind.Unsupported. Distinct from line 171 (whole case absent); line 180 fires when the case exists but the specific unit is flagged Unsupported.","commonSituations":"Requesting an instrumental/dative/genitive case under a Slavic or Turkic locale that declines some duration units (day, hour) but marks others (millisecond, week) unsupported; assuming a locale that 'has cases' supports them on every TimeUnit.","solutions":["Omit the grammaticalCase argument for that unit so it renders in the nominative default (FormatCaseAwareNominative).","Choose a locale whose case table marks the target unit Supported or SameAsNominative rather than Unsupported.","Wrap the call and fall back to the non-case Humanize overload on NotSupportedException."],"exampleFix":"// before\nvar s = ts.Humanize(2, TimeUnit.Day, culture: new CultureInfo(\"uk\"), grammaticalCase: GrammaticalCase.Genitive);\n\n// after — fall back to nominative when the case is unsupported for a unit\nstring s;\ntry\n{\n    s = ts.Humanize(2, TimeUnit.Day, culture: new CultureInfo(\"uk\"), grammaticalCase: GrammaticalCase.Genitive);\n}\ncatch (NotSupportedException)\n{\n    s = ts.Humanize(2, TimeUnit.Day, culture: new CultureInfo(\"uk\"));\n}","handlingStrategy":"try-catch","validationCode":"// No public API exposes per-unit case support; validate by attempting the case-aware call and catching.\n// If you know the locale, prefer the nominative default for units you have not verified:\nvar wantsCase = grammaticalCase != GrammaticalCase.Nominative;\n// (no pre-check available — use try-catch below)","typeGuard":null,"tryCatchPattern":"string rendered;\ntry\n{\n    rendered = ts.Humanize(maxUnit, minUnit, culture: culture, grammaticalCase: grammaticalCase);\n}\ncatch (NotSupportedException)\n{\n    // Locale does not inflect this unit for the requested case; fall back to nominative.\n    rendered = ts.Humanize(maxUnit, minUnit, culture: culture);\n}","preventionTips":["Prefer the no-case Humanize overloads unless you have verified the locale inflects every TimeUnit you will emit.","For Slavic/Turkic locales, test each TimeUnit you plan to surface (Millisecond and Week are commonly Unsupported).","Keep a per-locale allowlist of (GrammaticalCase, TimeUnit) pairs you have confirmed Supported."],"tags":["localization","timespan","grammatical-case"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}