withastro/astro · error · AstroError
Error generating routes: ${normalized.error.message}
Error message
Error generating routes: ${normalized.error.message} What it means
Thrown by the Vercel adapter when `normalizeRoutes()` (combining redirects + final routes) returns an `error`. This is a broader routing-consistency failure than the redirect-only check, covering conflicts between your Astro routes and Vercel's route table (duplicate paths, conflicting rewrites, invalid patterns).
Source
Thrown at packages/integrations/vercel/src/index.ts:611
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)) {
images.remotePatterns?.push(pattern);
}
}
} else if (imageService) {
images = getDefaultImageConfig(_config.image);
}
const normalized = normalizeRoutes([...(redirects ?? []), ...finalRoutes]);
if (normalized.error) {
throw new AstroError(
`Error generating routes: ${normalized.error.message}`,
normalized.error.link
? `${normalized.error.action ?? 'More info'}: ${normalized.error.link}`
: undefined,
);
}
if (_routeToHeaders && _routeToHeaders.size > 0) {
if (!normalized.routes) {
normalized.routes = [];
}
if (staticHeaders) {
const routesWithConfigHeaders = createRoutesWithStaticHeaders(_routeToHeaders, _config);
const fileSystemRouteIndex = normalized.routes.findIndex(
(r) => 'handle' in r && r.handle === 'filesystem',
);
normalized.routes.splice(fileSystemRouteIndex, 0, ...routesWithConfigHeaders);
}View on GitHub (pinned to d081033d5f)
Solutions
- Inspect `normalized.error.message` and `normalized.error.link` for the precise conflict.
- Eliminate duplicate or overlapping route paths across pages and redirects.
- Make `trailingSlash` and `build.format` consistent so normalized paths are unique.
Example fix
// before: page route /about and redirect /about -> /about/ collide
// after: remove the redirect or rename the page
export default defineConfig({
redirects: { '/about-old': '/about/' },
}); Defensive patterns
Strategy: try-catch
Validate before calling
const normalized = normalizeRoutes([...redirects, ...routes]);
if (normalized.error) { console.error('Route conflict:', normalized.error.message); } Type guard
function hasNormalizedError(r: unknown): r is { error: { message: string } } {
return !!(r as any)?.error;
} Try / catch
try { /* build */ } catch (e) { if (/Error generating routes/) { /* dedupe overlapping routes */ } else throw e; } Prevention
- Avoid overlapping page and redirect paths.
- Keep `trailingSlash` and `build.format` consistent.
- Review route tables after migrations.
When it happens
Trigger: Two routes resolving to the same normalized path. A route pattern Vercel cannot represent. Redirects colliding with page routes. Inconsistent `trailingSlash`/`build.format` producing ambiguous outputs.
Common situations: Migrating routes that overlap. Adding a redirect that targets an existing page route. Changing `build.format` ('file' vs 'directory') without updating redirects.
Related errors
- Error generating redirects: ${error.message}
- [RSS] You can only glob entries within 'src/pages/' when pas
- Invalid route ${file} — brackets are unbalanced
- Invalid route ${file} — rest parameter must be a standalone
- GetStaticPathsRequired
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/c716d31730e3b6ec.
Report an issue: GitHub.