Humanizr/Humanizer · error · NotSupportedException

Culture '{culture.Name}' does not resolve to simplified or t

Error message

Culture '{culture.Name}' does not resolve to simplified or traditional Chinese.

What it means

Thrown by ToChineseFinancialCharacters when the supplied CultureInfo does not resolve, via its parent chain, to either 'zh-Hans' (simplified) or 'zh-Hant' (traditional). The method walks culture.Parent until the name is empty and throws NotSupportedException if neither neutral Chinese culture is found. Only cultures within the simplified or traditional Chinese hierarchy are supported.

Source

Thrown at src/Humanizer/ChineseFinancialNumeralExtensions.cs:68

    /// </remarks>
    public static string ToChineseFinancialCharacters(this long number, CultureInfo culture)
    {
        ArgumentNullException.ThrowIfNull(culture);

        for (var current = culture; !string.IsNullOrEmpty(current.Name); current = current.Parent)
        {
            if (current.Name == "zh-Hans")
            {
                return SimplifiedConverter.Convert(number);
            }

            if (current.Name == "zh-Hant")
            {
                return TraditionalConverter.Convert(number);
            }
        }

        throw new NotSupportedException(
            $"Culture '{culture.Name}' does not resolve to simplified or traditional Chinese.");
    }

    static EastAsianGroupedNumberToWordsConverter CreateConverter(
        string negativePrefix,
        string[] digitWords,
        string[] largeUnits) =>
        new(new(
            "零",
            negativePrefix,
            "",
            "",
            digitWords,
            ["", "拾", "佰", "仟"],
            largeUnits,
            false,
            false,
            false,

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Pass an explicit culture in the zh-Hans or zh-Hant family, e.g. CultureInfo.GetCultureInfo("zh-Hans") for simplified or "zh-Hant" for traditional.
  2. If the culture comes from user/request data, validate that its name starts with 'zh-' before calling, and choose Hans vs Hant explicitly.
  3. When you only have a bare 'zh' tag, decide the script explicitly and construct the neutral culture yourself rather than relying on resolution.

Example fix

// before
var s = amount.ToChineseFinancialCharacters(CultureInfo.CurrentCulture);

// after
var culture = CultureInfo.GetCultureInfo(simplified ? "zh-Hans" : "zh-Hant");
var s = amount.ToChineseFinancialCharacters(culture);
Defensive patterns

Strategy: validation

Validate before calling

static bool ResolvesToChinese(CultureInfo c)
{
    for (var cur = c; !string.IsNullOrEmpty(cur.Name); cur = cur.Parent)
        if (cur.Name is "zh-Hans" or "zh-Hant") return true;
    return false;
}
if (!ResolvesToChinese(culture))
    throw new NotSupportedException("Pass a zh-Hans or zh-Hant culture.");
var s = number.ToChineseFinancialCharacters(culture);

Type guard

static bool IsChineseCulture(CultureInfo c) =>
    c.Name.StartsWith("zh-", StringComparison.OrdinalIgnoreCase);

Try / catch

try { return number.ToChineseFinancialCharacters(culture); }
catch (NotSupportedException) { /* pick a default script */ return number.ToChineseFinancialCharacters(CultureInfo.GetCultureInfo("zh-Hans")); }

Prevention

When it happens

Trigger: Calling number.ToChineseFinancialCharacters(CultureInfo.GetCultureInfo("en-US")), passing CultureInfo.InvariantCulture, passing the neutral "zh" culture (which is neither Hans nor Hant), or passing a regional culture like "zh-SG" only if its parent chain reaches zh-Hans (it does, so that case succeeds).

Common situations: Using the ambient CurrentCulture (e.g. a server set to en-US) and forgetting to pass an explicit Chinese culture; passing a culture built from an ISO code that does not carry the Hans/Hant script subtag; locale-detection logic that maps 'Chinese' to the bare 'zh' tag.

Related errors


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