Humanizr/Humanizer · error · ArgumentException
Empty or invalid Roman numeral string.
Error message
Empty or invalid Roman numeral string.
What it means
Thrown by FromRoman when the input span is empty after trimming or contains characters that do not form a valid Roman numeral. Valid Roman numerals use only M, D, C, L, X, V, and I (case-insensitive) with subtractive notation. Humanizer validates the character set before computing the integer value.
Source
Thrown at src/Humanizer/RomanNumeralExtensions.cs:119
/// This is a memory-efficient overload that works with character spans to avoid string allocations.
/// Valid Roman numerals use the characters M, D, C, L, X, V, and I (case-insensitive).
/// Supports subtractive notation (e.g., IV = 4, IX = 9).
/// </remarks>
/// <example>
/// <code>
/// "XIV".AsSpan().FromRoman() => 14
/// "MCMXC".AsSpan().FromRoman() => 1990
/// </code>
/// </example>
public static int FromRoman(CharSpan input)
{
input = input.Trim();
var length = input.Length;
if (length == 0 || IsInvalidRomanNumeral(input))
{
throw new ArgumentException("Empty or invalid Roman numeral string.", nameof(input));
}
var total = 0;
var i = length;
while (i > 0)
{
var digit = GetRomanNumeralCharValue(input[--i]);
if (i > 0)
{
var previousDigit = GetRomanNumeralCharValue(input[i - 1]);
if (previousDigit < digit)
{
digit -= previousDigit;
i--;
}
}
View on GitHub (pinned to ffc2b77c0f)
Solutions
- Check that the input is non-empty and contains only valid Roman numeral characters before calling FromRoman.
- Use a try/catch around ArgumentException to handle invalid input gracefully.
- Sanitize upstream data to filter out non-Roman strings.
Example fix
// before
var value = input.AsSpan().FromRoman();
// after
static bool IsValidRoman(ReadOnlySpan<char> s) =>
!s.Trim().IsEmpty &&
s.Trim().IndexOfAnyExceptIn("MDCLXVImdclxvi".AsSpan()) < 0;
var value = IsValidRoman(input.AsSpan())
? input.AsSpan().FromRoman()
: 0; Defensive patterns
Strategy: validation
Validate before calling
static bool IsValidRomanNumeral(ReadOnlySpan<char> input)
{
var trimmed = input.Trim();
return !trimmed.IsEmpty &&
trimmed.IndexOfAnyExceptIn("MDCLXVImdclxvi".AsSpan()) < 0;
} Type guard
static bool IsRomanNumeral(ReadOnlySpan<char> input) =>
IsValidRomanNumeral(input); Try / catch
try
{
return input.AsSpan().FromRoman();
}
catch (ArgumentException ex) when (ex.Message.Contains("Roman numeral"))
{
return 0;
} Prevention
- Filter input to valid Roman characters before calling FromRoman.
- Use a regex like ^[MDCLXVI]+$ (case-insensitive) for quick validation.
- Handle empty or null spans before the call.
When it happens
Trigger: Calling "".AsSpan().FromRoman(), " ".AsSpan().FromRoman(), or "ABC".AsSpan().FromRoman(). Also fires for numerals with invalid repetition patterns or non-Roman characters.
Common situations: Parsing user input or data-file fields that may contain non-Roman text. Reading from a column that is sometimes blank. Passing lowercased or Unicode-variant Roman characters that fail validation.
Related errors
- Empty or invalid Metric string.
- Precision must be greater than zero.
- 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/d661233c0218d8cb.
Report an issue: GitHub.