withastro/astro · error · AstroError

Error generating redirects

Error message

Error generating redirects: ${error.message}

What it means

During `astro build` with the Vercel adapter, your `redirects` config is transformed into Vercel's routing format via `getTransformedRoutes`. If that transformation reports an error, the adapter rethrows it as an AstroError prefixed with "Error generating redirects", passing through the underlying message and optional docs link. The root cause is a redirects entry that cannot be expressed in Vercel's route format.

Solutions

  1. Read the appended underlying `error.message` (and the "More info" link) — it names the exact offending redirect
  2. Check each redirects entry: `from` must be a route pattern like '/old/:path' or '/blog/[slug]', `to` a valid target, `status` 301/302/308/307
  3. Set `trailingSlash: 'ignore'` temporarily to see if the slash rule is what breaks the transform
  4. Simplify the failing redirect to a static from/to pair, or move dynamic redirects into middleware

Example fix

// before
redirects: [{ from: '/docs/**:rest', to: '/guides/:rest', status: 301 }],

// after
redirects: [{ from: '/docs/:rest(.*)', to: '/guides/:rest', status: 301 }],
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await build(); // or astro build via CLI
} catch (e) {
  if (e instanceof AstroError && e.message.startsWith('Error generating redirects')) {
    // e.message embeds the underlying reason; inspect config.redirects
  }
  throw e;
}

Prevention

When it happens

Trigger: A `redirects: [{ from: ..., to: ... }]` entry in astro.config with an invalid or unsupported source pattern (bad dynamic param syntax, malformed path), or a pattern that conflicts with the `trailingSlash` setting (`trailingSlash: 'always' | 'never'` gets mapped into the transform and can invalidate certain redirect sources).

Common situations: Adding redirects copied from another adapter (Netlify `_redirects` syntax left in config), upgrading Astro/Vercel adapter majors where redirect transformation rules tightened, or combining dynamic redirect sources with a non-'ignore' trailingSlash.

Related errors


AI-assisted analysis of withastro/astro@3578d45d34 (2026-08-18). Data as JSON: /api/errors/57edeae6082bc947. Report an issue: GitHub.

Appendix: source

Thrown at packages/integrations/vercel/src/index.ts:601

				let trailingSlash: boolean | undefined;
				// Vercel's `trailingSlash` option maps to Astro's like so:
				// - `true` -> `"always"`
				// - `false` -> `"never"`
				// - `undefined` -> `"ignore"`
				// If config is set to "ignore", we leave it as undefined.
				if (_config.trailingSlash && _config.trailingSlash !== 'ignore') {
					// Otherwise, map it accordingly.
					trailingSlash = _config.trailingSlash === 'always';
				}

				const { routes: redirects = [], error } = getTransformedRoutes({
					trailingSlash,
					rewrites: [],
					redirects: getRedirects(routes, _config),
					headers: [],
				});
				if (error) {
					throw new AstroError(
						`Error generating redirects: ${error.message}`,
						error.link ? `${error.action ?? 'More info'}: ${error.link}` : undefined,
					);
				}

				let images: VercelImageConfig | undefined;
				if (imagesConfig) {
					images = {
						...imagesConfig,
						domains:
							imagesConfig.domains || _config.image.domains
								? [...(imagesConfig.domains ?? []), ...(_config.image.domains ?? [])]
								: undefined,
						remotePatterns: [...(imagesConfig.remotePatterns ?? [])],
					};
					const remotePatterns = _config.image.remotePatterns;
					for (const pattern of remotePatterns) {
						if (isAcceptedPattern(pattern)) {

View on GitHub (pinned to 3578d45d34)