RocketChat/Rocket.Chat · warning · Meteor.Error
moment-locale-not-found
moment-locale-not-found
Error message
Moment locale not found: ${locale} What it means
getMomentLocale tries three bundled asset paths for the requested locale — the exact lowercased code (e.g. pt-br), the language-only prefix (pt), and a mapped variant from mapLocaleToMomentLocale (ug→ug-cn, zh→zh-cn) — and throws this Meteor.Error when none of the moment-locales/*.js assets exist. The server then cannot serve the moment.js locale file for that language.
Source
Thrown at apps/meteor/server/lib/getMomentLocale.ts:22
ug: 'ug-cn',
zh: 'zh-cn',
};
export async function getMomentLocale(locale: string): Promise<string | undefined> {
const localeLower = locale.toLowerCase();
const localesPaths = [
`moment-locales/${localeLower}.js`,
`moment-locales/${String(localeLower.split('-').shift())}.js`,
`moment-locales/${mapLocaleToMomentLocale[localeLower]}.js`,
];
for await (const localePath of localesPaths) {
try {
return await Assets.getTextAsync(localePath);
} catch (error) {
continue;
}
}
throw new Meteor.Error('moment-locale-not-found', `Moment locale not found: ${locale}`);
}
View on GitHub (pinned to b2c16d5842)
Solutions
- Use a supported language/locale code for the setting that feeds getMomentLocale
- For custom locales, add the moment-locales/<locale>.js server asset and, when the moment name differs, an entry in mapLocaleToMomentLocale
- As a caller, catch this error and fall back to the 'en' locale
Example fix
// before
const localeSrc = await getMomentLocale(locale);
// after
let localeSrc: string | undefined;
try {
localeSrc = await getMomentLocale(locale);
} catch (err) {
if (err instanceof Meteor.Error && err.error === 'moment-locale-not-found') {
localeSrc = await getMomentLocale('en');
} else {
throw err;
}
} Defensive patterns
Strategy: fallback
Validate before calling
const SUPPORTED_MOMENT_LOCALES = ['en', 'de', 'pt-br', 'zh-cn' /* ... */]; const localeLower = locale.toLowerCase(); const safeLocale = SUPPORTED_MOMENT_LOCALES.includes(localeLower) ? locale : 'en';
Try / catch
try {
return await getMomentLocale(locale);
} catch (err) {
if (err instanceof Meteor.Error && err.error === 'moment-locale-not-found') {
return getMomentLocale('en'); // graceful degradation to default locale
}
throw err;
} Prevention
- Stick to officially supported language codes
- When adding custom languages, ship the matching moment-locales asset and update mapLocaleToMomentLocale
- Never let locale loading break request handling — always fall back to 'en'
When it happens
Trigger: A user's language resolves to a locale code with no matching bundled moment asset: unsupported/odd region variants, or custom language packs that added translations but no moment locale file and no mapLocaleToMomentLocale entry.
Common situations: Custom locale added without shipping the moment asset or updating the mapping; deployments where server assets are incomplete; clients requesting unusual Accept-Language variants.
Related errors
- Moment locale not found: ${locale}
- Command does not exist in the system currently (or it is dis
- FileUpload_Error
- Invalid asset
- This_conversation_is_already_closed
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/651b950a8edb6688.
Report an issue: GitHub.