{"record":{"id":"0b87e21b16939fbc","repo":"dotnet/runtime","slug":"locale-info-for-locale-localename-is-null-or-em-0b87e2","errorCode":null,"errorMessage":"Locale info for locale=${localeName} is null or empty.","messagePattern":"Locale info for locale=(.+?) is null or empty\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/native/libs/System.Native.Browser/native/globalization-locale.ts","lineNumber":63,"sourceCode":"                        // handle non-standard or malformed locales by forwarding the locale code, e.g. \"xx-u-xx\"\n                        _ems_.dotnetBrowserUtilsExports.stringToUTF16(dst, dst + 2 * localeNameOriginal.length, localeNameOriginal);\n                        _ems_.dotnetApi.setHeapI32(dstLength, localeNameOriginal.length);\n                        return 0 as any;\n                    }\n                    throw error;\n                }\n            } else {\n                throw error;\n            }\n        }\n        const localeInfo = {\n            LanguageName: languageName,\n            RegionName: regionName,\n        };\n        const result = Object.values(localeInfo).join(OUTER_SEPARATOR);\n\n        if (!result)\n            throw new Error(`Locale info for locale=${localeName} is null or empty.`);\n\n        if (result.length > dstMaxLength)\n            throw new Error(`Locale info for locale=${localeName} exceeds length of ${dstMaxLength}.`);\n\n        _ems_.dotnetBrowserUtilsExports.stringToUTF16(dst, dst + 2 * result.length, result);\n        _ems_.dotnetApi.setHeapI32(dstLength, result.length);\n        return 0 as any;\n    } catch (ex: any) {\n        _ems_.dotnetApi.setHeapI32(dstLength, -1);\n        return _ems_.dotnetBrowserUtilsExports.stringToUTF16Ptr(ex.toString());\n    }\n\n    function normalizeLocale(locale: string | null) {\n        if (!locale)\n            return undefined;\n        try {\n            locale = locale.toLocaleLowerCase().replace(\"_\", \"-\");\n            if (locale.startsWith(\"zh-\")) {","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/native/libs/System.Native.Browser/native/globalization-locale.ts#L45-L81","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","solutions":["Upgrade the host runtime to one with full Intl.DisplayNames data (full-icu / a modern browser).","Use a more standard, resolvable locale/culture pair.","Catch the marshaled error in .NET and fall back to the invariant culture."],"exampleFix":"// before: exotic locale whose names can't be resolved\nIntl.DisplayNames([\"xx\"], {type:\"language\"}).of(\"qaa\") // -> undefined -> empty result\n\n// after: use a resolvable, well-known culture\nnew CultureInfo(\"en-US\");","handlingStrategy":"fallback","validationCode":"function canResolveDisplayNames(locale, culture) {\n  try {\n    const lang = new Intl.DisplayNames([culture], { type: \"language\" }).of(locale.split(\"-\")[0]);\n    return !!lang;\n  } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"// .NET caller: check returned length; on -1 fall back to invariant culture\nint len = GetLocaleInfo(locale, culture, ...);\nif (len < 0) info = GetLocaleInfo(\"en-US\", \"en-US\", ...);","preventionTips":["Prefer well-known culture codes for display-name resolution.","Test globalization paths on all target browsers, not just Chromium.","Treat locale display-name resolution as fallible with an invariant-culture fallback."],"tags":["globalization","intl-displaynames","locale"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}