Humanizr/Humanizer · error · ArgumentException

Unrecognized number word: {unrecognizedWord}

Error message

Unrecognized number word: {unrecognizedWord}

What it means

This ArgumentException is thrown by EastAsianPositionalWordsToNumberConverter.Convert when TryConvert fails. This converter parses positional number words (Chinese/Japanese/Korean style) composed of digits, small units (tens/hundreds), and large units (thousands/ten-thousands). The error fires when the normalized input contains a character or multi-character token that is not in the locale's digit, small-unit, or large-unit token tables.

Source

Thrown at src/Humanizer/Localisation/WordsToNumber/EastAsianPositionalWordsToNumberConverter.cs:15

namespace Humanizer;

/// <summary>
/// Parses East Asian positional number words made up of digits, small units, and large units.
/// </summary>
internal class EastAsianPositionalWordsToNumberConverter(EastAsianPositionalWordsToNumberProfile profile) : GenderlessWordsToNumberConverter
{
    readonly EastAsianPositionalWordsToNumberProfile profile = profile;

    /// <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.");
        }

        var normalized = words.Replace(" ", string.Empty).Trim();

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Use TryToNumber(words, out value, culture, out unrecognizedWord) for any input that may be invalid.
  2. Verify the input uses the correct script and character set for the target locale.
  3. Pre-filter input to known digit and unit characters if the source is unstructured text.
  4. Check the unrecognizedWord to identify the offending character or token.

Example fix

// before
long value = input.ToNumber(new CultureInfo("ja"));

// after
if (!input.TryToNumber(out var value, new CultureInfo("ja"), out var bad))
    Console.WriteLine($"Unrecognized token: {bad}");
Defensive patterns

Strategy: try-catch

Validate before calling

bool canParse = words.TryToNumber(out var value, culture, out var unrecognized);
if (!canParse)
    Console.WriteLine($"Unrecognized token: {unrecognized}");

Type guard

static bool LooksLikeNumberWords(string words, CultureInfo culture) =>
    !string.IsNullOrWhiteSpace(words) && words.TryToNumber(out _, culture, out _);

Try / catch

try
{
    return words.ToNumber(new CultureInfo("ja"));
}
catch (ArgumentException ex) when (ex.Message.Contains("Unrecognized number word"))
{
    return 0;
}

Prevention

When it happens

Trigger: Calling "words".ToNumber(culture) for an East Asian positional locale with a string containing characters not registered as digits or units, or mixing scripts from different locales.

Common situations: User input containing non-numeric CJK characters; mixing Simplified Chinese characters with a Japanese locale or vice versa; passing Latin-alphabet words to a CJK locale; input with Unicode variants or full-width characters not in the token map; ordinal affixes the locale did not configure.

Related errors


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