withastro/astro · error · AstroError

Error generating redirects: ${error.message}

Error message

Error generating redirects: ${error.message}

What it means

Thrown by the Vercel adapter during `astro:build:done` when `getTransformedRoutes()` (Vercel's route normalizer) returns an `error` object while processing redirects. Astro forwards the message and, if present, a 'More info' link.

Source

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

				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 d081033d5f)

Solutions

  1. Read the embedded `error.message`/`error.link` — Vercel states the specific rule violated.
  2. Simplify the `redirects` config and re-add entries incrementally to isolate the offender.
  3. Align `trailingSlash` config with redirect destination paths.

Example fix

// before: redirect destination missing trailing slash while trailingSlash: 'always'
export default defineConfig({
  trailingSlash: 'always',
  redirects: { '/old': '/new' },
});
// after
export default defineConfig({
  trailingSlash: 'always',
  redirects: { '/old': '/new/' },
});
Defensive patterns

Strategy: try-catch

Validate before calling

const { error } = getTransformedRoutes({ /* ... */ });
if (error) { console.error('Redirect rule violated:', error.message, error.link); }

Type guard

function hasRouteError(r: unknown): r is { error: { message: string; link?: string } } {
  return !!(r as any)?.error;
}

Try / catch

try { /* build */ } catch (e) { if (/Error generating redirects/) { /* inspect e.message, fix redirects */ } else throw e; }

Prevention

When it happens

Trigger: A `redirects` config entry that violates Vercel's routing rules (invalid path syntax, too many redirects, circular redirect, unsupported wildcard). A trailing-slash setting that conflicts with redirect definitions. Route count exceeding Vercel plan limits.

Common situations: Adding many redirects in `vercel.json` or Astro `redirects`. Mixing `trailingSlash: 'always'` with redirect targets that lack trailing slashes. Hitting Vercel plan route caps.

Related errors


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