Humanizr/Humanizer · error · ArgumentException

Unrecognized number word: {unrecognizedWord}

Error message

Unrecognized number word: {unrecognizedWord}

What it means

TokenMapWordsToNumberConverter.Convert throws this ArgumentException at line 31 when TryConvert cannot map the phrase under the token-map grammar (the most common English-style converter). It supports optional invariant-integer fast input, exact/glued ordinal maps, and compact glued-scale tokens. Only Convert raises it; the Try overloads return false with the unrecognized token.

Source

Thrown at src/Humanizer/Localisation/WordsToNumber/TokenMapWordsToNumberConverter.cs:31

{
    const int MaxCompactGluedScaleCountLength = 96;
    const int MaxCompactGluedScaleTokenCount = 16;
    const int MaxCompactGluedScaleStatesPerPosition = 128;
    const int MaxGluedScaleDepth = 8;

    readonly TokenMapWordsToNumberRules rules = rules;
    readonly FrozenDictionary<string, long>? exactOrdinalMap = rules.ExactOrdinalMap;
    readonly FrozenDictionary<string, long>? ordinalScaleMap = rules.OrdinalScaleMap;
    readonly FrozenDictionary<string, long>? gluedOrdinalScaleSuffixes = rules.GluedOrdinalScaleSuffixes;
    readonly FrozenDictionary<string, long>? gluedScaleSuffixes = rules.GluedScaleSuffixes;
    Dictionary<char, List<CompactGluedScaleToken>>? compactGluedScaleTokensByFirstCharacter;

    /// <inheritdoc />
    public override long Convert(string words)
    {
        if (!TryConvert(words, out var parsedValue, out var unrecognizedWord))
        {
            throw new ArgumentException($"Unrecognized number word: {unrecognizedWord}");
        }

        return parsedValue;
    }

    /// <inheritdoc />
    public override bool TryConvert(string words, out long parsedValue) =>
        TryConvert(words, out parsedValue, out _);

    /// <inheritdoc />
    public override bool TryConvert(string words, out long parsedValue, out string? unrecognizedWord)
    {
        if (string.IsNullOrWhiteSpace(words))
        {
            throw new ArgumentException("Input words cannot be empty.");
        }

        if (rules.AllowInvariantIntegerInput &&

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Switch to TryToNumber(words, out var n, culture, out var bad) and handle false.
  2. Use bad to locate the offending token and fix the input.
  3. For numeric digit strings, rely on the invariant-integer fast path if AllowInvariantIntegerInput is enabled for the locale.
  4. Confirm the phrase's language matches the culture (registry falls back to English for unsupported locales).

Example fix

// before
var n = "twenty banana".ToNumber(CultureInfo.GetCultureInfo("en"));
// after
if ("twenty banana".TryToNumber(out var n, CultureInfo.GetCultureInfo("en"), out var bad))
    Use(n);
else
    Warn($"unrecognized token: {bad}");
Defensive patterns

Strategy: validation

Validate before calling

if (!words.TryToNumber(out var n, culture, out var unrecognized))
    return Result.Fail($"unrecognized token: {unrecognized}");
return Result.Ok(n);

Try / catch

try { var n = words.ToNumber(culture); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Unrecognized number word"))
    { /* handle */ }

Prevention

When it happens

Trigger: Calling ToNumber with tokens absent from the cardinal/ordinal/glued maps and not a bare integer (when AllowInvariantIntegerInput is on). Fires at line 31 when TryConvert returns false.

Common situations: The default English converter rejecting foreign or misspelled words; free-form user text; ordinals fed to the integer path; punctuation or case the normalizer does not fold.

Related errors


AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13). Data as JSON: /api/errors/952cfc8ab04a6358. Report an issue: GitHub.