Humanizr/Humanizer · error · ArgumentException
Decimal marker must not be empty.
Error message
Decimal marker must not be empty.
What it means
LocalizedWordsToDecimalNumberConverter's constructor throws this ArgumentException at line 28 when decimalMarker normalizes to an empty string. The decimal grammar needs exactly one locale-specific marker to split integer and fractional parts, so an empty marker is unrecoverable. The converter is internal and built from locale data, so an empty marker is a locale-authoring defect.
Source
Thrown at src/Humanizer/Localisation/WordsToNumber/LocalizedWordsToDecimalNumberConverter.cs:28
readonly CompareInfo compareInfo;
readonly string decimalMarker;
readonly FractionalDigit[] fractionalDigits;
readonly IWordsToNumberConverter integerConverter;
readonly bool allowsJoinedTokens;
readonly bool allowsEnglishOverflowComposition;
readonly NegativeAffix[] negativePrefixes;
readonly NegativeAffix[] negativeSuffixes;
public LocalizedWordsToDecimalNumberConverter(
CultureInfo culture,
string decimalMarker,
string[] negativePrefixes,
string[] negativeSuffixes)
{
compareInfo = culture.CompareInfo;
this.decimalMarker = NormalizeWhitespace(decimalMarker);
if (this.decimalMarker.Length == 0)
throw new ArgumentException("Decimal marker must not be empty.", nameof(decimalMarker));
integerConverter = Configurator.GetWordsToNumberConverter(culture);
allowsJoinedTokens = integerConverter is EastAsianPositionalWordsToNumberConverter;
allowsEnglishOverflowComposition =
string.Equals(culture.TwoLetterISOLanguageName, "en", StringComparison.OrdinalIgnoreCase);
this.negativePrefixes = NormalizePrefixes(negativePrefixes);
this.negativeSuffixes = NormalizeSuffixes(negativeSuffixes);
fractionalDigits = CreateFractionalDigits(culture);
}
internal string DecimalMarker => decimalMarker;
/// <inheritdoc />
public decimal Convert(string words)
{
ArgumentNullException.ThrowIfNull(words);
if (!TryConvert(words, out var parsedValue, out var unrecognizedNumber))View on GitHub (pinned to ffc2b77c0f)
Solutions
- Provide a non-empty locale-specific decimal marker (e.g. 'point', 'virgule', the localized 'and'-style token) in the locale decimal configuration.
- Regenerate locale source and run the locale's decimal word tests.
- Add a construction assertion in locale tests verifying the converter builds for that culture.
Example fix
// before (locale decimal config) decimalMarker: "" // after decimalMarker: "point", // localized marker for splitting integer/fractional words
Defensive patterns
Strategy: validation
Validate before calling
// Authoring-time guard: confirm the decimal converter builds for the culture. var decimalConverter = Configurator.GetWordsToDecimalNumberConverter(targetCulture); Assert.False(decimalConverter is UnsupportedWordsToDecimalNumberConverter);
Prevention
- Provide a non-empty locale-specific decimal marker in the decimal config.
- Add a locale test that constructs the decimal converter and asserts it is not the unsupported stub.
- Regenerate locale source after changing decimal data.
When it happens
Trigger: A locale's decimal-word configuration supplies an empty or whitespace-only decimal marker; the marker value is stripped to empty by NormalizeWhitespace; or the generator wires an empty marker. Construction happens lazily when ToDecimalNumber/TryToDecimalNumber first resolves the culture.
Common situations: A new locale with decimal words added but its decimal marker key left blank; a YAML typo that yields an empty string; regenerating after a marker rename.
Related errors
- Teen prefix cannot be empty.
- Unrecognized decimal number word: {unrecognizedNumber}
- Scale-leading compound parser profiles require descending sc
- Scale-leading compound parser profiles require positive scal
- Decimal word parsing is not supported for the requested cult
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/b914c77cc2429a22.
Report an issue: GitHub.