abpframework / abpframework/abp
registerLocaleForEsBuild() returns undefined -> bootstrap crash "Cannot read properties of undefined (reading 'then')" for cultures absent from its hardcoded localeSupportList (e.g. ja, ko, vi)
@sumeyyeKurtulus is already working on this.
Since Jul 1, 2026.
- Dominant language
- C#
- Stars
- 14.4k
- Forks
- 3.7k
- Avg merge
- 15h 32m
- Merged PRs (30d)
- 106
Description
Is there an existing issue for this?
- I have searched the existing issues. Related but distinct from #21483: that one fixed
cultureNameLocaleFileMapnot being respected (checkinglocaleinstead of the mappedl). This report is about cultures absent fromlocaleSupportListentirely, where no mapping can help and the earlyreturn;yieldsundefined.
Description
registerLocaleForEsBuild() (npm/ng-packs/packages/core/locale/src/utils/register-locale.ts) hardcodes a 20-entry locale list. For any active culture whose (mapped) value l is not in that list, the returned function hits return; → undefined, before it ever reaches the loadLocale(l).catch(errorHandlerFn) fallback. ABP's locale APP_INITIALIZER then calls registerLocaleFn(locale).then(...) on that undefined:
TypeError: Cannot read properties of undefined (reading 'then')
Bootstrap is aborted → blank app for every user whose active culture resolves to a non-listed language (ja, ko, vi, th, …).
Two things make this distinct from #21483 and hard to work around with configuration alone:
cultureNameLocaleFileMapcannot help: it can only remap a culture onto another listed locale file, and there is no listed file carrying Japanese (or Korean/Vietnamese/Thai) data. A backend with Japanese enabled in Language Management therefore blank-screens anyjaclient with no config-only fix.- The documented
storeLocaleDataescape hatch also doesn't help on the esbuild path — its data is only read byerrorHandlerFn, which lives inside theloadLocale(l).catch(...)that the earlyreturn;never reaches.
The declared return type is Promise<any>, but the return; branch actually returns undefined, so callers that trust the type (ABP's own locale initializer) crash.
Reproduction Steps
import { registerLocaleForEsBuild } from '@abp/ng.core/locale';
registerLocaleForEsBuild()('ja').then(x => console.log(x));
// TypeError: Cannot read properties of undefined (reading 'then')
End-to-end: enable Japanese (ja) in Language Management, build the Angular app with the esbuild application builder (Angular 17+ default) using registerLocaleFn: registerLocaleForEsBuild(), then open the app with Accept-Language: ja (or with ja persisted in localStorage) → blank app with the error above.
Expected behavior
An unsupported culture should degrade gracefully — return a resolved Promise (and/or route through errorHandlerFn / consult the extraLocales populated by storeLocaleData), never undefined, so bootstrap can't crash. Ideally the esbuild loadLocale list should also cover the cultures ABP ships localization resources for (e.g. ja, ko).
Actual behavior
return; yields undefined; the initializer's .then() throws; the app is blank for the affected users.
Regression?
No. Present since the esbuild loader was introduced; still present on the current dev branch (verified register-locale.ts today). The fix for #21483 (checking l instead of locale) did not touch this return;/undefined path.
Known Workarounds
Wrap registerLocaleFn in app.config.ts to (a) load the extra locale yourself via a literal import('@angular/common/locales/ja') + storeLocaleData, and (b) never return undefined for any unlisted culture:
import { registerLocaleForEsBuild, storeLocaleData } from '@abp/ng.core/locale';
const extra: Record<string, () => Promise<unknown>> = {
ja: () => import('@angular/common/locales/ja'),
};
const abp = registerLocaleForEsBuild();
const registerLocaleFn = (locale: string) => {
const handled = abp(locale);
if (handled) return handled; // listed cultures: unchanged
const load = extra[locale];
if (!load) return Promise.resolve({ default: null }); // unknown culture: safe no-op, never undefined
return load()
.then(m => { let d: any = m; while (d?.default) d = d.default; storeLocaleData(d, locale); return { default: d }; })
.catch(() => ({ default: null }));
};
// provideAbpCore(withOptions({ environment, registerLocaleFn }))
Suggested fix
Replace the bare return; with return Promise.resolve({ default: null }); (or route unsupported locales through errorHandlerFn, which already consults extraLocales), and/or extend the loadLocale / localeSupportList set to the cultures ABP ships resources for.
Version
@abp/ng.core 10.4.1 (source identical on the current dev branch; reported through 10.5.0). Angular 21, esbuild application builder.
User Interface
Angular
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.