withastro/astro · error · AstroError
InvalidI18nMiddlewareConfiguration
InvalidI18nMiddlewareConfiguration
Error message
The option `redirectToDefaultLocale` can be enabled only when `prefixDefaultLocale` is also set to `true`; otherwise, redirects might cause infinite loops. Enable the option `prefixDefaultLocale` to continue to use `redirectToDefaultLocale`, or ensure both are set to `false`.
What it means
Thrown (code `InvalidI18nMiddlewareConfiguration`) when the user-provided i18n middleware options set `prefixDefaultLocale: false` together with `redirectToDefaultLocale: true`. Without a prefix on the default locale, redirecting to it has no distinct URL to redirect to, producing infinite redirect loops. The check guards a combination the type system also forbids (`@ts-expect-error` marks the runtime check).
Source
Thrown at packages/astro/src/virtual-modules/i18n.ts:402
* });
*
* export const onRequest = sequence(customLogic, middleware({
* prefixDefaultLocale: true,
* redirectToDefaultLocale: false
* }))
*
* ```
*/
export let middleware: (customOptions: I18nMiddlewareOptions) => MiddlewareHandler;
if (i18n?.routing === 'manual') {
middleware = (customOptions) => {
if (
customOptions.prefixDefaultLocale === false &&
// @ts-expect-error types do not allow this but we also check at runtime
customOptions.redirectToDefaultLocale === true
) {
throw new AstroError(InvalidI18nMiddlewareConfiguration);
}
strategy = toRoutingStrategy(customOptions, {});
fallbackType = toFallbackType(customOptions);
const manifest: SSRManifest['i18n'] = {
...i18n,
strategy,
domainLookupTable: {},
fallbackType,
fallback: i18n.fallback,
domains: i18n.domains,
};
return I18nInternals.createMiddleware(manifest, base, trailingSlash, format);
};
} else {
middleware = noop('middleware');
}
/**View on GitHub (pinned to d081033d5f)
Solutions
- Set both options to false: `middleware({ prefixDefaultLocale: false, redirectToDefaultLocale: false })` — serve the default locale at root without redirect.
- Or set both to true: `middleware({ prefixDefaultLocale: true, redirectToDefaultLocale: true })` — prefix every locale including the default.
- Pick one consistent pair; never mix false/true for these two.
Example fix
// before
import { middleware } from 'astro:i18n';
export const onRequest = middleware({ prefixDefaultLocale: false, redirectToDefaultLocale: true });
// after
export const onRequest = middleware({ prefixDefaultLocale: false, redirectToDefaultLocale: false }); Defensive patterns
Strategy: validation
Validate before calling
function validateMiddlewareOptions(opts) {
if (opts.prefixDefaultLocale === false && opts.redirectToDefaultLocale === true) {
throw new Error('redirectToDefaultLocale requires prefixDefaultLocale: true');
}
} Prevention
- Never set prefixDefaultLocale:false with redirectToDefaultLocale:true.
- Treat the two options as a coupled pair: both true or both false.
- Add a config test that asserts your middleware options do not violate the invariant.
When it happens
Trigger: Calling `middleware({ prefixDefaultLocale: false, redirectToDefaultLocale: true })` imported from `astro:i18n`. This branch only exists inside the `i18n.routing === 'manual'` middleware factory, so it requires manual routing to be enabled.
Common situations: Copy-pasting middleware options from a project that prefixed the default locale into one that does not. Disabling `prefixDefaultLocale` to serve the default locale at `/` but forgetting to also disable `redirectToDefaultLocale`. Misunderstanding that the two options are coupled.
Related errors
- MissingMiddlewareForInternationalization
- MissingIndexForInternationalizationError
- IncorrectStrategyForI18n
- CannotOptimizeSvg
- RemoteImageNotAllowed
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/78269821839f8fa4.
Report an issue: GitHub.