Humanizr/Humanizer · error · OverflowException
Cannot safely negate long.MinValue.
Error message
Cannot safely negate long.MinValue.
What it means
OverflowException guard inside the WholePhrasePrefix ordinal path: negating long.MinValue is undefined in two's complement, so the renderer refuses it rather than producing a wrapped value. Note that the shipped public API is ConvertToOrdinal(int), and int.MinValue (cast to long) is never equal to long.MinValue, so this branch is currently unreachable through the public ordinal entry point; the guard is defensive for any future long-based ordinal caller of ConvertWholePhraseOrdinal.
Source
Thrown at src/Humanizer/Localisation/NumberToWords/ConjunctionalScaleNumberToWordsConverter.cs:193
}
parts.Add(string.Concat(
tens,
profile.TensUnitsSeparator,
GetUnitValue(units, isOrdinal)));
return;
}
parts.Add(GetUnitValue(number, isOrdinal));
}
string ConvertWholePhraseOrdinal(long number, bool addAnd)
{
if (number < 0)
{
if (number == long.MinValue)
{
throw new OverflowException("Cannot safely negate long.MinValue.");
}
return $"{profile.MinusWord} {ConvertWholePhraseOrdinal(-number, addAnd)}";
}
if (number < profile.OrdinalUnitsMap.Length)
{
return GetUnitValue(number, isOrdinal: true);
}
return $"{profile.OrdinalWholePhrasePrefix}{ConvertCore(number, isOrdinal: false, addAnd)}";
}
string GetUnitValue(long number, bool isOrdinal) =>
isOrdinal ? profile.OrdinalUnitsMap[number] : profile.UnitsMap[number];
// "and" placement is modeled as a structural rule family rather than as locale branches.
// The generated profile says which insertion points are legal, and this method translates thatView on GitHub (pinned to ffc2b77c0f)
Solutions
- No action needed for the current int-based ordinal API.
- If adding a long ordinal overload, reject long.MinValue at the entry point before delegating to ConvertWholePhraseOrdinal.
Defensive patterns
Strategy: validation
Validate before calling
// Currently unreachable via ConvertToOrdinal(int); guard only if you add a long ordinal overload:
static string SafeOrdinalWords(long number)
{
if (number == long.MinValue)
{
throw new ArgumentOutOfRangeException(nameof(number), number, "long.MinValue has no negatable ordinal form.");
}
// ...delegate to the converter
} Prevention
- Do not extend ConvertWholePhraseOrdinal to long.MinValue without a guard.
- When adding long ordinal overloads, reject long.MinValue at the entry point.
When it happens
Trigger: Not reachable via the public ConvertToOrdinal(int) API today, since int.MinValue != long.MinValue. Would only fire if a future overload invoked ConvertWholePhraseOrdinal(long.MinValue, addAnd) directly while OrdinalMode == WholePhrasePrefix.
Common situations: Not user-reachable in the current release; documented for completeness and for anyone extending the converter with a long ordinal overload.
Related errors
- Failed to project metric scale words for locale '{locale.Loc
- Array-backed metric scale word contracts require a value pro
- Unsupported number-to-words contract member kind '{member.Ki
- Enum members require an enum type.
- Builder members require a builder name.
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/1ebd0434a21ce5dd.
Report an issue: GitHub.