{"record":{"id":"89b3e9351f7fa9fe","repo":"Humanizr/Humanizer","slug":"gender","errorCode":null,"errorMessage":"gender","messagePattern":"gender","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Humanizer/Localisation/NumberToWords/TerminalOrdinalScaleNumberToWordsConverter.cs","lineNumber":215,"sourceCode":"    /// Returns the cardinal ending for a unit stem.\n    /// </summary>\n    static string GetCardinalUnitEnding(GrammaticalGender gender, int number)\n    {\n        return NormalizeGender(gender) switch\n        {\n            GrammaticalGender.Masculine => number switch\n            {\n                1 => \"s\",\n                < 10 when number != 3 => \"i\",\n                _ => string.Empty\n            },\n            GrammaticalGender.Feminine => number switch\n            {\n                1 => \"a\",\n                < 10 when number != 3 => \"as\",\n                _ => string.Empty\n            },\n            _ => throw new ArgumentOutOfRangeException(nameof(gender))\n        };\n    }\n\n    /// <summary>\n    /// Returns the ordinal suffix for the requested gender.\n    /// </summary>\n    string GetOrdinalSuffix(GrammaticalGender gender) =>\n        NormalizeGender(gender) switch\n        {\n            GrammaticalGender.Masculine => profile.MasculineOrdinalSuffix,\n            GrammaticalGender.Feminine => profile.FeminineOrdinalSuffix,\n            _ => throw new ArgumentOutOfRangeException(nameof(gender))\n        };\n\n    static GrammaticalGender NormalizeGender(GrammaticalGender gender) =>\n        gender == GrammaticalGender.Neuter ? GrammaticalGender.Masculine : gender;\n\n    static ulong GetAbsoluteValue(long value) =>","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer/Localisation/NumberToWords/TerminalOrdinalScaleNumberToWordsConverter.cs#L197-L233","documentation":"This ArgumentOutOfRangeException is a defensive exhaustiveness guard inside GetCardinalUnitEnding, a static method on TerminalOrdinalScaleNumberToWordsConverter. The switch only patterns Masculine and Feminine after NormalizeGender has already mapped Neuter to Masculine, so every valid GrammaticalGender value is consumed before the discard arm. The throw fires only when the caller supplies an enum value outside the three declared members (e.g. an unchecked cast such as (GrammaticalGender)42).","triggerScenarios":"Calling Convert(number, gender) or ConvertToOrdinal(number, gender) on a locale backed by TerminalOrdinalScaleNumberToWordsConverter with a GrammaticalGender value produced by an invalid cast or deserialized from corrupt data rather than one of the declared enum literals.","commonSituations":"Deserializing a GrammaticalGender from an integer column or JSON payload that was never validated; forwarding a gender typed as int or byte through a boundary without range-checking; unit tests that synthesize enum values via reflection or unchecked casts.","solutions":["Ensure the GrammaticalGender value is always one of Masculine, Feminine, or Neuter — validate at the trust boundary before calling ToWords/ConvertToOrdinal.","If the value originates from deserialization or an integer source, guard with Enum.IsDefined(typeof(GrammaticalGender), value) before passing it.","Map any unknown gender to a safe default (typically GrammaticalGender.Masculine) at the call site so invalid upstream data degrades gracefully instead of crashing."],"exampleFix":"// before\nvar gender = (GrammaticalGender)userInput;\nreturn number.ToWords(gender, culture);\n\n// after\nif (!Enum.IsDefined(typeof(GrammaticalGender), userInput))\n    throw new ArgumentOutOfRangeException(nameof(userInput));\nvar gender = (GrammaticalGender)userInput;\nreturn number.ToWords(gender, culture);","handlingStrategy":"validation","validationCode":"bool IsValidGender(GrammaticalGender gender) =>\n    gender is GrammaticalGender.Masculine\n        or GrammaticalGender.Feminine\n        or GrammaticalGender.Neuter;\n\n// or for untrusted integer sources:\nbool IsValidGenderCode(int code) =>\n    Enum.IsDefined(typeof(GrammaticalGender), code);","typeGuard":"static bool IsDefinedGender(GrammaticalGender gender) =>\n    Enum.IsDefined(typeof(GrammaticalGender), gender);","tryCatchPattern":"try\n{\n    return number.ToWords(gender, culture);\n}\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"gender\")\n{\n    return number.ToWords(GrammaticalGender.Masculine, culture);\n}","preventionTips":["Validate GrammaticalGender at every boundary where the value originates from external or serialized data.","Prefer binding enums by name in JSON/deserialization rather than by raw integer.","Use Enum.IsDefined in integration layers to reject phantom enum values before they reach Humanizer.","Enable nullable reference types and treat enum validation as a trust-boundary concern."],"tags":["argumentoutofrange","grammatical-gender","number-to-words","defensive-guard"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}