withastro/astro · error · AstroError

InvalidRedirectDestination

InvalidRedirectDestination

Error message

The redirect from "${from}" to "${to}" is invalid. The destination "${to}" does not match any existing route in your project.

What it means

InvalidRedirectDestination: a redirect whose SOURCE has dynamic params points to a destination that is not a parseable URL and does not match any existing route in the project, while prerenderDefault is on. With dynamic source params, Astro needs a real destination route to map them at build time; an unmapped destination would later fail with a misleading error, so it is caught early.

Source

Thrown at packages/astro/src/core/routing/create-manifest.ts:559

		if (URL.canParse(destination) && !/^https?:\/\//.test(destination)) {
			throw new AstroError({
				...UnsupportedExternalRedirect,
				message: UnsupportedExternalRedirect.message(from, destination),
			});
		}

		const redirectRoute = routeMap.get(destination);

		// If the source has dynamic params and the redirect will be prerendered,
		// we need a valid redirectRoute to map them. Without it, the build will fail
		// later with a misleading error. Catch this early and provide a clear error message.
		if (
			params.length > 0 &&
			!redirectRoute &&
			!URL.canParse(destination) &&
			getPrerenderDefault(config)
		) {
			throw new AstroError({
				...InvalidRedirectDestination,
				message: InvalidRedirectDestination.message(from, destination),
			});
		}

		// If the source has dynamic params and the destination route exists but has
		// fewer params, the build will fail later with a misleading error (e.g.,
		// "getStaticPaths required" pointing at the wrong file). Catch this early.
		if (
			params.length > 0 &&
			redirectRoute &&
			!URL.canParse(destination) &&
			getPrerenderDefault(config)
		) {
			const destParams = redirectRoute.params ?? [];
			const missingParams = params.filter((p) => !destParams.includes(p));
			if (missingParams.length > 0) {
				throw new AstroError({

View on GitHub (pinned to d081033d5f)

Solutions

  1. Create the destination route so it exists in the project, or correct the typo.
  2. If the destination is a full URL, use http(s):// so URL.canParse treats it as external.
  3. Disable prerendering for the source (prerender = false) so the redirect is resolved at runtime.
  4. Remove the dynamic param from the source if the destination is truly static.

Example fix

// before
redirects: { '/old/[slug]': '/missing/[slug]' } // /missing/[slug] page absent

// after — create src/pages/missing/[slug].astro, or point to existing route
redirects: { '/old/[slug]': '/posts/[slug]' }
Defensive patterns

Strategy: validation

Validate before calling

function destinationRouteExists(dest: string, routes: string[]): boolean {
  if (URL.canParse(dest)) return true; // external
  return routes.includes(dest);
}
// cross-check dynamic-redirect destinations against the route list

Prevention

When it happens

Trigger: Configuring redirects: { '/old/[slug]': '/new/[slug]' } when /new/[slug] does not exist; destination is a bare path with no matching page; typo in the destination route.

Common situations: Renaming/renaming routes but forgetting to update redirects; redirects pointing to yet-to-be-created pages; copying redirects from another project whose routes differ.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/f018f9d0ab18275d. Report an issue: GitHub.