withastro/astro · error · AstroError

MissingLocaleError

MissingLocaleError

Error message

The locale/path `${locale}` does not exist in the configured `i18n.locales`.

What it means

getLocaleRelativeUrl() builds a locale-prefixed URL from your i18n config. It first resolves the passed `locale` against the configured `i18n.locales` (via peekCodePathToUse, matching either a locale code or a custom path). If nothing matches, it throws MissingLocale: the locale/path you passed does not exist in `i18n.locales`.

Solutions

  1. Add the locale to `i18n.locales` in astro.config if it should be supported.
  2. Pass one of the configured values exactly - a locale code or a custom path - matching case.
  3. Validate locale strings from user input against the configured locales before calling i18n URL utilities.

Example fix

// before - 'fr' is not configured (locales: ['en', 'es'])
const url = getLocaleRelativeUrl({ locale: 'fr', locales: ['en', 'es'], path: '' });

// after - enable it in astro.config
export default defineConfig({
  i18n: { defaultLocale: 'en', locales: ['en', 'es', 'fr'] },
});
// or use a configured locale
const url = getLocaleRelativeUrl({ locale: 'es', locales: ['en', 'es'], path: '' });
Defensive patterns

Strategy: type-guard

Type guard

const LOCALES = ['en', 'es'] as const;
type Locale = (typeof LOCALES)[number];
function isKnownLocale(l: string): l is Locale {
  return (LOCALES as readonly string[]).includes(l);
}
if (isKnownLocale(userLocale)) {
  const url = getLocaleRelativeUrl({ locale: userLocale, locales: [...LOCALES], path: '' });
}

Prevention

When it happens

Trigger: Calling getLocaleRelativeUrl({ locale: 'fr', ... }) when i18n.locales is ['en', 'es']; passing a custom path or code with the wrong casing ('FR' vs 'fr'); passing a locale read from a cookie or user profile without checking it against the configured list.

Common situations: A language switcher hardcoding a locale that was never enabled; locales coming from user settings or headers that are broader than the configured set; copy-pasting i18n config between projects where the locale lists differ.

Related errors


AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18). Data as JSON: /api/errors/d5abca6eb252f296. Report an issue: GitHub.

Appendix: source

Thrown at packages/astro/src/i18n/index.ts:69

/**
 * The base URL
 */
export function getLocaleRelativeUrl({
	locale,
	base,
	locales: _locales,
	trailingSlash,
	format,
	path,
	prependWith,
	normalizeLocale = true,
	strategy = 'pathname-prefix-other-locales',
	defaultLocale,
}: GetLocaleRelativeUrl) {
	const codeToUse = peekCodePathToUse(_locales, locale);
	if (!codeToUse) {
		throw new AstroError({
			...MissingLocale,
			message: MissingLocale.message(locale),
		});
	}
	const pathsToJoin = [base, prependWith];
	const normalizedLocale = normalizeLocale ? normalizeTheLocale(codeToUse) : codeToUse;
	if (
		strategy === 'pathname-prefix-always' ||
		strategy === 'pathname-prefix-always-no-redirect' ||
		strategy === 'domains-prefix-always' ||
		strategy === 'domains-prefix-always-no-redirect'
	) {
		pathsToJoin.push(normalizedLocale);
	} else if (locale !== defaultLocale) {
		pathsToJoin.push(normalizedLocale);
	}
	pathsToJoin.push(path);

View on GitHub (pinned to 52e6c34790)