Humanizr/Humanizer · error · ArgumentOutOfRangeException

Unknown number-to-words profile.

Error message

Unknown number-to-words profile.

What it means

This message is emitted into generated source code (NumberToWordsProfileCatalog.g.cs) as the default case of a switch on the profile name. At runtime, NumberToWordsProfileCatalog.Resolve(kind, culture) throws ArgumentOutOfRangeException when the kind string is not one of the profile names compiled into the catalog. The catalog only knows profiles that shipped from the locale YAML included in that build.

Source

Thrown at src/Humanizer.SourceGenerators/Generators/ProfileCatalogs/NumberToWordsProfileCatalogInput.cs:79

            builder.AppendLine("static partial class NumberToWordsProfileCatalog");
            builder.AppendLine("{");
            builder.AppendLine("    public static INumberToWordsConverter Resolve(string kind, CultureInfo culture)");
            builder.AppendLine("    {");
            builder.AppendLine("        switch (kind)");
            builder.AppendLine("        {");

            foreach (var profile in profiles.OrderBy(static profile => profile.ProfileName, StringComparer.Ordinal))
            {
                var expression = CreateProfileExpression(profile, useCultureParameter: RequiresCulture(profile));
                builder.Append("            case ");
                builder.Append(QuoteLiteral(profile.ProfileName));
                builder.Append(": return ");
                builder.Append(RequiresCulture(profile) ? expression : GetCatalogPropertyName(profile.ProfileName));
                builder.AppendLine(";");
            }

            builder.AppendLine("        }");
            builder.AppendLine("        throw new ArgumentOutOfRangeException(nameof(kind), kind, \"Unknown number-to-words profile.\");");
            builder.AppendLine("    }");
            builder.AppendLine();

            foreach (var profile in profiles.OrderBy(static profile => profile.ProfileName, StringComparer.Ordinal))
            {
                if (RequiresCulture(profile))
                {
                    continue;
                }

                AppendLazyCachedMember(
                    builder,
                    "    ",
                    "static",
                    "INumberToWordsConverter",
                    GetCatalogPropertyName(profile.ProfileName),
                    CreateProfileExpression(profile, useCultureParameter: false));
                builder.AppendLine();

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Verify the locale is present under src/Humanizer/Locales and its numberToWords block has a profile name that matches the kind string you are passing.
  2. Ensure the locale's numberToWords feature is registered with UsesGeneratedProfile: true so it appears in the generated catalog switch.
  3. If you are calling the API with a CultureInfo, confirm its Name property resolves to a supported locale (e.g. 'en', 'fr', 'de').
  4. Fall back to a known-supported locale (the default is 'en') when the requested locale is not available.

Example fix

// before — 'xx' is not a shipped number-to-words locale
var words = NumberToWords.ToWords(42, "xx");

// after — use a supported locale
var words = NumberToWords.ToWords(42, "en");
Defensive patterns

Strategy: validation

Validate before calling

// Before calling a number-to-words API with an arbitrary locale,
// verify the locale is supported.
var culture = new CultureInfo("fr");
// The public API falls back gracefully for unsupported locales via the registry default.
// If calling NumberToWordsProfileCatalog.Resolve directly (internal), guard the name:
if (!IsSupportedNumberToWordsLocale(culture.Name))
    culture = CultureInfo.InvariantCulture; // or 'en'

Try / catch

try
{
    var converter = NumberToWordsProfileCatalog.Resolve(kind, culture);
}
catch (ArgumentOutOfRangeException)
{
    // Fall back to the default 'en' profile
    converter = NumberToWordsProfileCatalog.Resolve("en", culture);
}

Prevention

When it happens

Trigger: Calling a number-to-words API (e.g. number.ToWords(...)) with a culture/locale whose name does not match any generated profile. This can happen if the locale's numberToWords feature was not marked UsesGeneratedProfile, or the locale was never included in the build, or the caller passes an ad-hoc string that is not a known culture identifier.

Common situations: A consumer upgrades Humanizer and a previously supported locale name changed or was removed. A consumer calls the internal registry with a custom or mistyped culture string. A developer working on locale parity calls Resolve directly with an unfinished profile name during testing.

Related errors


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