{"record":{"id":"ecbc1d2bb155f4ac","repo":"Humanizr/Humanizer","slug":"specified-argument-was-out-of-the-range-of-valid-v-ecbc1d","errorCode":null,"errorMessage":"Specified argument was out of the range of valid values. (Parameter 'maxDenominator')","messagePattern":"Specified argument was out of the range of valid values\\. \\(Parameter 'maxDenominator'\\)","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Humanizer/FractionalizeExtensions.cs","lineNumber":47,"sourceCode":"    /// <example>\n    /// <code>\n    /// 1.25m.Fractionalize(5, 0m) => \"1 1/4\"\n    /// 0.34m.Fractionalize(5, 0.01m) => \"1/3\"\n    /// 0.75m.Fractionalize(4, 0m, useUnicode: true) => \"¾\"\n    /// </code>\n    /// </example>\n    public static string Fractionalize(\n        this decimal input,\n        int maxDenominator,\n        decimal tolerance,\n        bool useUnicode = false)\n    {\n#if NET8_0_OR_GREATER\n        ArgumentOutOfRangeException.ThrowIfLessThan(maxDenominator, 1);\n        ArgumentOutOfRangeException.ThrowIfNegative(tolerance);\n#else\n        if (maxDenominator < 1)\n            throw new ArgumentOutOfRangeException(nameof(maxDenominator));\n        if (tolerance < 0)\n            throw new ArgumentOutOfRangeException(nameof(tolerance));\n#endif\n\n        if (decimal.Truncate(input) == input)\n            return input.ToString(\"0\", CultureInfo.InvariantCulture);\n\n        var value = ToFraction(input);\n        var approximation = LimitDenominator(BigInteger.Abs(value.Numerator), value.Denominator, maxDenominator);\n        if (value.Numerator.Sign < 0)\n            approximation.Numerator = -approximation.Numerator;\n\n        if (!IsWithinTolerance(value, approximation, ToFraction(tolerance)))\n            return input.ToString(LocaleNumberFormattingOverrides.GetFormattingNumberFormat(CultureInfo.CurrentCulture));\n\n        return Format(approximation, useUnicode);\n    }\n","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer/FractionalizeExtensions.cs#L29-L65","documentation":"Thrown by Fractionalize when maxDenominator is less than 1. On .NET 8+ it uses ArgumentOutOfRangeException.ThrowIfLessThan(maxDenominator, 1); on older targets it throws manually. A denominator of 1 (whole numbers only) is allowed. The parameter is named 'maxDenominator'.","triggerScenarios":"Calling value.Fractionalize(0, 0m) or value.Fractionalize(-5, 0.01m); passing a maxDenominator derived from user input or configuration without a lower bound; computing the denominator from a precision setting that can evaluate to zero or negative.","commonSituations":"Exposing maxDenominator as a user-tunable precision knob with no min validation; defaulting the argument from an optional config value that is missing and falls back to 0; arithmetic that subtracts a safety margin and underflows.","solutions":["Clamp maxDenominator to at least 1 before calling: Math.Max(1, requestedDenominator).","Validate the source configuration/int input at the boundary and reject values below 1 with a clear error.","Choose a sensible application default (e.g. 64 or 100) and only override with validated input."],"exampleFix":"// before\nvar f = value.Fractionalize(maxDenominatorFromConfig, tolerance);\n\n// after\nvar denom = Math.Max(1, maxDenominatorFromConfig);\nvar f = value.Fractionalize(denom, tolerance);","handlingStrategy":"validation","validationCode":"if (maxDenominator < 1)\n    throw new ArgumentOutOfRangeException(nameof(maxDenominator), \"Must be >= 1.\");\nvar f = input.Fractionalize(maxDenominator, tolerance);","typeGuard":"static bool IsValidMaxDenominator(int d) => d >= 1;","tryCatchPattern":"try { return input.Fractionalize(maxDenominator, tolerance); }\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"maxDenominator\")\n{ return input.Fractionalize(1, tolerance); }","preventionTips":["Clamp user-supplied denominators to a minimum of 1.","Validate config values at the boundary before they reach Fractionalize.","Pick an application default denominator (e.g. 64) and only override with checked input."],"tags":["argument-validation","fractional","numeric","argument-out-of-range"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}