{"record":{"id":"67c0aa4b567e1a0f","repo":"Humanizr/Humanizer","slug":"unsupported-grammatical-case","errorCode":null,"errorMessage":"Unsupported grammatical case.","messagePattern":"Unsupported grammatical case\\.","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Humanizer/Localisation/Formatters/DefaultFormatter.cs","lineNumber":144,"sourceCode":"        }\n\n        return category;\n    }\n\n    string IGrammaticalCaseTimeSpanFormatter.TimeSpanHumanize(\n        TimeUnit timeUnit,\n        int unit,\n        GrammaticalCase grammaticalCase)\n    {\n        if (GetType().Assembly != typeof(DefaultFormatter).Assembly)\n        {\n            throw new NotSupportedException(\n                $\"Custom formatter type '{GetType().FullName}' must explicitly implement {nameof(IGrammaticalCaseTimeSpanFormatter)} to support grammatical-case-aware durations.\");\n        }\n\n        if ((uint)grammaticalCase > (uint)GrammaticalCase.Causal)\n        {\n            throw new ArgumentOutOfRangeException(nameof(grammaticalCase), grammaticalCase, \"Unsupported grammatical case.\");\n        }\n\n        if ((uint)timeUnit > (uint)TimeUnit.Year)\n        {\n            throw new ArgumentOutOfRangeException(nameof(timeUnit), timeUnit, \"Unsupported time unit.\");\n        }\n\n        var table = LocaleDurationCaseTableCatalog.Resolve(Culture)\n            ?? throw new NotSupportedException(\n                $\"Culture '{Culture.Name}' has no grammatical-case classification for duration phrases.\");\n\n        if (table.Classification == LocaleDurationCaseClassification.Unsupported)\n        {\n            throw new NotSupportedException(\n                $\"Culture '{Culture.Name}' has an applicable grammatical case system, but verified duration forms are unavailable.\");\n        }\n\n        if (table.Classification == LocaleDurationCaseClassification.NotApplicable)","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs#L126-L162","documentation":"Thrown in IGrammaticalCaseTimeSpanFormatter.TimeSpanHumanize when the grammaticalCase argument is not a defined member of the GrammaticalCase enum. The guard casts to uint and compares against (uint)GrammaticalCase.Causal (the last defined member), so any value above Causal or a negative cast-to-large-uint fails. The exception is ArgumentOutOfRangeException named 'grammaticalCase' with the offending value in the message.","triggerScenarios":"Calling the case-aware formatter with (GrammaticalCase)999; passing a GrammaticalCase deserialized from an out-of-range integer; default(GrammaticalCase) is Nominative (0) and is valid so it will NOT throw.","commonSituations":"Configuration/serialization storing the case as a raw int; interop with another enum cast to GrammaticalCase; reflection-based callers that construct the value dynamically.","solutions":["Validate with Enum.IsDefined(typeof(GrammaticalCase), grammaticalCase) before invoking the case-aware path.","Parse the case from strings via Enum.TryParse<GrammaticalCase> and reject unknown tokens.","When you only need the nominative form, use the non-case-aware TimeSpanHumanize(timeUnit, unit) overload."],"exampleFix":"// before\nvar text = formatter.TimeSpanHumanize(unit, count, (GrammaticalCase)caseCode);\n\n// after\nif (!Enum.IsDefined(typeof(GrammaticalCase), caseCode))\n    throw new ArgumentOutOfRangeException(nameof(caseCode));\nvar text = formatter.TimeSpanHumanize(unit, count, (GrammaticalCase)caseCode);","handlingStrategy":"validation","validationCode":"if (!Enum.IsDefined(typeof(GrammaticalCase), grammaticalCase))\n    throw new ArgumentOutOfRangeException(nameof(grammaticalCase));\nvar text = caseFormatter.TimeSpanHumanize(timeUnit, unit, grammaticalCase);","typeGuard":"static bool IsValidGrammaticalCase(GrammaticalCase c) => Enum.IsDefined(typeof(GrammaticalCase), c);","tryCatchPattern":"try { return caseFormatter.TimeSpanHumanize(timeUnit, unit, grammaticalCase); }\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"grammaticalCase\")\n{ return caseFormatter.TimeSpanHumanize(timeUnit, unit, GrammaticalCase.Nominative); }","preventionTips":["Validate GrammaticalCase at the boundary with Enum.IsDefined.","Parse from strings with Enum.TryParse<GrammaticalCase>.","Prefer the non-case-aware overload when you only need the nominative form."],"tags":["grammatical-case","argument-validation","formatter","argument-out-of-range"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}