{"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/60108ba66eb7d1d12f595480091b4ad80a24b172/src/native/libs/System.Native.Browser/native/globalization-locale.ts#L45-L81","documentation":"After resolving LanguageName and RegionName through Intl.DisplayNames, the code joins them with '##'. If the resulting string is empty (both names were undefined/empty) this error fires. It means the Intl provider accepted the locale and culture but returned no display text for either component.","triggerScenarios":"Intl.DisplayNames([cultureName], {type:'region'}).of(region) and the language variant both return undefined or empty, producing an empty join. Happens with locales whose region/script the runtime's Intl data does not have display names for.","commonSituations":"Running on a JS engine with reduced ICU data (older Node without full-icu, embedded WebView) where DisplayNames has no data for the requested language/region; a private-use or rare locale (e.g. 'qaa-RU') that canonicalizes but has no display strings.","solutions":["Use full-icu / a Node build with complete ICU data so Intl.DisplayNames has entries for the locale.","Switch the culture to a well-known locale with full display-name coverage (e.g. en-US, fr-FR) to confirm the path works, then narrow down the unsupported locale.","On the .NET side, fall back to a parent/neutral culture (e.g. 'en' instead of 'en-xxx') when display names are unavailable."],"exampleFix":"// before: locale with no display-name data\nvar ci = new CultureInfo(\"qaa-RU\");\n\n// after: well-known locale with ICU coverage\nvar ci = new CultureInfo(\"ru-RU\");","handlingStrategy":"validation","validationCode":"// Probe Intl.DisplayNames coverage for a locale/culture before relying on it.\nfunction hasDisplayNames(locale: string, culture: string): boolean {\n  try {\n    const lang = new Intl.DisplayNames([culture], { type: \"language\" }).of(locale);\n    return typeof lang === \"string\" && lang.length > 0;\n  } catch {\n    return false;\n  }\n}\n\nif (!hasDisplayNames(target, uiCulture)) {\n  target = \"en\"; // fallback with known coverage\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Use full-icu / a runtime with complete ICU data for Intl.DisplayNames.","Prefer well-known locales with broad display-name coverage for UI culture.","Fall back to a neutral/parent culture when display names are unavailable.","Smoke-test exotic locales in your target environment during CI."],"tags":["globalization","locale","i18n","intl","display-names"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}