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

Thrown by SystemJS_GetLocaleInfo after it successfully resolves the locale but Intl.DisplayNames returns empty values for both LanguageName and RegionName, producing an empty result string (joined by '##'). This is the runtime's internal bridge that converts a .NET culture/locale request into a JS-side display-name lookup, and it signals that the locale is recognized but its human-readable parts could not be produced.

Source

Thrown at src/mono/browser/runtime/globalization-locale.ts:82

                        // handle non-standard or malformed locales by forwarding the locale code, e.g. "xx-u-xx"
                        stringToUTF16(dst, dst + 2 * localeNameOriginal.length, localeNameOriginal);
                        setI32(dstLength, localeNameOriginal.length);
                        return VoidPtrNull;
                    }
                    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}.`);

        stringToUTF16(dst, dst + 2 * result.length, result);
        setI32(dstLength, result.length);
        return VoidPtrNull;
    } catch (ex: any) {
        setI32(dstLength, -1);
        return stringToUTF16Ptr(ex.toString());
    }
}

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. Ship the full ICU data for your app (set globalization mode to use the full ICU .dat) so Intl.DisplayNames has the needed entries.
  2. Verify the culture string passed from .NET is a well-formed BCP-47 tag (e.g. 'en-US', 'zh-Hans-CN') and not a malformed/custom value.
  3. Upgrade the host browser/engine to one with complete Intl.DisplayNames support.
  4. If the locale is intentionally non-standard, let the runtime forward it by ensuring normalizeLocale falls into the forwarding path rather than reaching the empty-result assertion.

Example fix

// before: app runs with invariant/minimal globalization
// dotnet.withConfig({ resources: { /* no icu assets */ } })

// after: provide full ICU data asset
// <WasmIcuData Include="icudt.dat" />
// or via config:
dotnet.withConfig({
  resources: { icu: [{ behavior: 'icu', name: 'icudt.dat', hash: '...' }] }
});
Defensive patterns

Strategy: validation

Validate before calling

// Before requesting a specific culture, sanity-check it resolves display names
function localeInfoResolves(locale) {
  try {
    const c = Intl.getCanonicalLocales(locale.replace(/_/g,'-'))[0];
    const parts = c.split('-');
    const region = parts.length > 1 ? parts.pop() : undefined;
    const lang = new Intl.DisplayNames([c], { type: 'language' }).of(parts.join('-'));
    const reg = region ? new Intl.DisplayNames([c], { type: 'region' }).of(region) : undefined;
    return !!(lang || reg);
  } catch { return false; }
}
if (!localeInfoResolves(requestedCulture)) { /* use fallback culture or invariant */ }

Type guard

function isResolvableLocale(locale: string): boolean {
  try {
    return Intl.getCanonicalLocales(locale.replace(/_/g,'-')).length > 0;
  } catch { return false; }
}

Prevention

When it happens

Trigger: Triggered when the .NET runtime calls into JS to get locale display names (via the SystemJS_GetLocaleInfo P/Invoke) and the constructed `result = LanguageName##RegionName` is falsy. Occurs with unusual or under-specified culture strings where Intl.DisplayNames.of() returns undefined for both the language and region components.

Common situations: Running under a minimal ICU dataset (invariant or subsetted globalization) where the requested culture's display names are not available; using a locale like a custom/privately-registered culture; running in an older JS engine whose Intl.DisplayNames lacks coverage for the requested language.

Related errors


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