dotnet/runtime · error · Error

Locale info for locale=${localeName} is null or empty.

Error message

Locale info for locale=${localeName} is null or empty.

What it means

After resolving LanguageName and RegionName via Intl.DisplayNames, the joined result (values joined by "##") is checked for emptiness. If both display names came back undefined/empty the function has no usable locale info to write and throws. The surrounding catch marshals the message to .NET with dstLength=-1.

Source

Thrown at src/native/libs/System.Native.Browser/native/globalization-locale.ts:63

                        // handle non-standard or malformed locales by forwarding the locale code, e.g. "xx-u-xx"
                        _ems_.dotnetBrowserUtilsExports.stringToUTF16(dst, dst + 2 * localeNameOriginal.length, localeNameOriginal);
                        _ems_.dotnetApi.setHeapI32(dstLength, localeNameOriginal.length);
                        return 0 as any;
                    }
                    throw error;
                }
            } else {
                throw error;
            }
        }
        const localeInfo = {
            LanguageName: languageName,
            RegionName: regionName,
        };
        const result = Object.values(localeInfo).join(OUTER_SEPARATOR);

        if (!result)
            throw new Error(`Locale info for locale=${localeName} is null or empty.`);

        if (result.length > dstMaxLength)
            throw new Error(`Locale info for locale=${localeName} exceeds length of ${dstMaxLength}.`);

        _ems_.dotnetBrowserUtilsExports.stringToUTF16(dst, dst + 2 * result.length, result);
        _ems_.dotnetApi.setHeapI32(dstLength, result.length);
        return 0 as any;
    } catch (ex: any) {
        _ems_.dotnetApi.setHeapI32(dstLength, -1);
        return _ems_.dotnetBrowserUtilsExports.stringToUTF16Ptr(ex.toString());
    }

    function normalizeLocale(locale: string | null) {
        if (!locale)
            return undefined;
        try {
            locale = locale.toLocaleLowerCase().replace("_", "-");
            if (locale.startsWith("zh-")) {

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. Upgrade the host runtime to one with full Intl.DisplayNames data (full-icu / a modern browser).
  2. Use a more standard, resolvable locale/culture pair.
  3. Catch the marshaled error in .NET and fall back to the invariant culture.

Example fix

// before: exotic locale whose names can't be resolved
Intl.DisplayNames(["xx"], {type:"language"}).of("qaa") // -> undefined -> empty result

// after: use a resolvable, well-known culture
new CultureInfo("en-US");
Defensive patterns

Strategy: fallback

Validate before calling

function canResolveDisplayNames(locale, culture) {
  try {
    const lang = new Intl.DisplayNames([culture], { type: "language" }).of(locale.split("-")[0]);
    return !!lang;
  } catch { return false; }
}

Try / catch

// .NET caller: check returned length; on -1 fall back to invariant culture
int len = GetLocaleInfo(locale, culture, ...);
if (len < 0) info = GetLocaleInfo("en-US", "en-US", ...);

Prevention

When it happens

Trigger: A locale that passes canonicalization but whose language/region Intl.DisplayNames.of() returns undefined — e.g. a locale with only a region and no resolvable language name in the requested culture, or a private-use subtag like 'qaa'.

Common situations: Rare/exotic or private-use locales; browsers or Node builds without full Intl.DisplayNames data (older Safari, Node without full-icu); a culture whose script the engine can't render display names for.

Related errors


AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06). Data as JSON: /api/errors/0b87e21b16939fbc. Report an issue: GitHub.