Humanizr/Humanizer · error · ArgumentOutOfRangeException
Specified argument was out of the range of valid values. (Pa
Error message
Specified argument was out of the range of valid values. (Parameter 'tolerance')
What it means
Thrown by Fractionalize when tolerance is negative. Tolerance represents the maximum absolute difference allowed between the input and its fractional approximation, so a negative value is meaningless; zero is allowed (exact match required). On .NET 8+ it uses ArgumentOutOfRangeException.ThrowIfNegative; otherwise a manual throw. The parameter is named 'tolerance'.
Source
Thrown at src/Humanizer/FractionalizeExtensions.cs:49
/// 1.25m.Fractionalize(5, 0m) => "1 1/4"
/// 0.34m.Fractionalize(5, 0.01m) => "1/3"
/// 0.75m.Fractionalize(4, 0m, useUnicode: true) => "¾"
/// </code>
/// </example>
public static string Fractionalize(
this decimal input,
int maxDenominator,
decimal tolerance,
bool useUnicode = false)
{
#if NET8_0_OR_GREATER
ArgumentOutOfRangeException.ThrowIfLessThan(maxDenominator, 1);
ArgumentOutOfRangeException.ThrowIfNegative(tolerance);
#else
if (maxDenominator < 1)
throw new ArgumentOutOfRangeException(nameof(maxDenominator));
if (tolerance < 0)
throw new ArgumentOutOfRangeException(nameof(tolerance));
#endif
if (decimal.Truncate(input) == input)
return input.ToString("0", CultureInfo.InvariantCulture);
var value = ToFraction(input);
var approximation = LimitDenominator(BigInteger.Abs(value.Numerator), value.Denominator, maxDenominator);
if (value.Numerator.Sign < 0)
approximation.Numerator = -approximation.Numerator;
if (!IsWithinTolerance(value, approximation, ToFraction(tolerance)))
return input.ToString(LocaleNumberFormattingOverrides.GetFormattingNumberFormat(CultureInfo.CurrentCulture));
return Format(approximation, useUnicode);
}
static (BigInteger Numerator, BigInteger Denominator) ToFraction(decimal value)
{View on GitHub (pinned to ffc2b77c0f)
Solutions
- Use Math.Abs(tolerance) or default to 0m when the computed tolerance is negative.
- Validate tolerance at the configuration boundary and reject negative values with a descriptive error.
- When you want an exact fraction, pass 0m explicitly rather than relying on a computed near-zero value.
Example fix
// before var f = value.Fractionalize(64, tolerance); // after var tol = tolerance < 0 ? 0m : tolerance; var f = value.Fractionalize(64, tol);
Defensive patterns
Strategy: validation
Validate before calling
if (tolerance < 0)
throw new ArgumentOutOfRangeException(nameof(tolerance), "Must be >= 0.");
var f = input.Fractionalize(maxDenominator, tolerance); Type guard
static bool IsValidTolerance(decimal t) => t >= 0;
Try / catch
try { return input.Fractionalize(maxDenominator, tolerance); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "tolerance")
{ return input.Fractionalize(maxDenominator, 0m); } Prevention
- Use Math.Abs or default to 0m when tolerance could be negative.
- Validate tolerance magnitude at the configuration source.
- Pass 0m explicitly for exact-fraction requirements.
When it happens
Trigger: Calling value.Fractionalize(64, -0.01m); passing a tolerance computed as a difference that can go negative; deserializing tolerance from config where a sign error or missing value yields a negative decimal.
Common situations: Tolerance derived from a percentage/epsilon that underflows to a small negative due to floating/decimal arithmetic; configuration stored as a magnitude with a sign flag that is misread; reusing an 'allowed error' field for another purpose.
Related errors
- Specified argument was out of the range of valid values. (Pa
- Specified argument was out of the range of valid values. (Pa
- Specified argument was out of the range of valid values. (Pa
- Specified argument was out of the range of valid values. (Pa
- Specified argument was out of the range of valid values. (Pa
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/cb4bf97fb1726e16.
Report an issue: GitHub.