{"record":{"id":"19e33c8f72572fd0","repo":"dotnet/runtime","slug":"locale-or-culture-name-is-null-or-empty-localenam","errorCode":null,"errorMessage":"Locale or culture name is null or empty. localeName=${localeName}, cultureName=${cultureName}","messagePattern":"Locale or culture name is null or empty\\. localeName=(.+?), cultureName=(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mono/browser/runtime/globalization-locale.ts","lineNumber":42,"sourceCode":"        return undefined;\n    }\n}\n\nexport function SystemJS_GetLocaleInfo (culture: number, cultureLength: number, locale: number, localeLength: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr): VoidPtr {\n    try {\n        const localeNameOriginal = utf16ToString(<any>locale, <any>(locale + 2 * localeLength));\n        const localeName = normalizeLocale(localeNameOriginal);\n        if (!localeName && localeNameOriginal) {\n            // handle non-standard or malformed locales by forwarding the locale code\n            stringToUTF16(dst, dst + 2 * localeNameOriginal.length, localeNameOriginal);\n            setI32(dstLength, localeNameOriginal.length);\n            return VoidPtrNull;\n        }\n        const cultureNameOriginal = utf16ToString(<any>culture, <any>(culture + 2 * cultureLength));\n        const cultureName = normalizeLocale(cultureNameOriginal);\n\n        if (!localeName || !cultureName)\n            throw new Error(`Locale or culture name is null or empty. localeName=${localeName}, cultureName=${cultureName}`);\n\n        const localeParts = localeName.split(\"-\");\n        // cultureName can be in a form of:\n        // 1) \"language\", e.g. \"zh\"\n        // 2) \"language-region\", e.g. \"zn-CN\"\n        // 3) \"language-script-region\", e.g. \"zh-Hans-CN\"\n        // 4) \"language-script\", e.g. \"zh-Hans\" (served in the catch block below)\n        let languageName, regionName;\n        try {\n            const region = localeParts.length > 1 ? localeParts.pop() : undefined;\n            // this line might fail if form 4 from the comment above is used:\n            regionName = region ? new Intl.DisplayNames([cultureName], { type: \"region\" }).of(region) : undefined;\n            const language = localeParts.join(\"-\");\n            languageName = new Intl.DisplayNames([cultureName], { type: \"language\" }).of(language);\n        } catch (error) {\n            if (error instanceof RangeError) {\n                // if it failed from this reason then cultureName is in a form \"language-script\", without region\n                try {","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/mono/browser/runtime/globalization-locale.ts#L24-L60","documentation":"Thrown by SystemJS_GetLocaleInfo in globalization-locale.ts when, after normalization via Intl.getCanonicalLocales, both localeName and cultureName resolve to falsy. The managed runtime calls this JS interop to obtain display names for a locale/culture pair, and an empty pair cannot be resolved. The exception is caught by the surrounding try block, written as dstLength=-1, and the error string is returned to managed code rather than aborting the process.","triggerScenarios":"Managed code calls the locale-info interop with null/empty strings for both locale and culture; a CultureInfo or RegionInfo with an empty name reaches the boundary; normalizeLocale returns undefined because Intl.getCanonicalLocales rejected the input.","commonSituations":"Invariant globalization mode combined with code that still requests locale display names; passing CurrentCulture before it is initialized; corrupt culture strings loaded from configuration.","solutions":["Pass a valid BCP-47 locale string (e.g. en-US) instead of an empty value.","Guard the managed caller to skip the interop when CultureInfo.Name is empty or invariant.","Ensure ICU/globalization data is loaded so the culture resolves to a non-empty name."],"exampleFix":"// before\nvar info = SystemJS_GetLocaleInfo(0, 0, 0, 0, ...);\n// after: supply real names\nvar info = SystemJS_GetLocaleInfo(culturePtr, cultureLen, localePtr, localeLen, ...);","handlingStrategy":"validation","validationCode":"// before calling the locale-info interop from managed code\nif (string.IsNullOrEmpty(localeName) || string.IsNullOrEmpty(cultureName))\n    return; // skip the interop","typeGuard":null,"tryCatchPattern":"// the JS side already catches and forwards the error string to managed;\n// on the managed side, treat a returned dstLength of -1 as a soft failure\nint dstLength = ReadInt(dstLengthPtr);\nif (dstLength == -1) { /* read error string, fall back to invariant name */ }","preventionTips":["Never pass empty locale/culture names to the interop.","Default to CultureInfo.InvariantCulture.Name when the requested culture is empty.","Ensure ICU/globalization data is loaded so cultures resolve to non-empty names."],"tags":["globalization","locale","interop","icu"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}