{"record":{"id":"57edeae6082bc947","repo":"withastro/astro","slug":"error-generating-redirects-error-message","errorCode":null,"errorMessage":"Error generating redirects: ${error.message}","messagePattern":"Error generating redirects: (.+?)","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/integrations/vercel/src/index.ts","lineNumber":601,"sourceCode":"\t\t\t\tlet trailingSlash: boolean | undefined;\n\t\t\t\t// Vercel's `trailingSlash` option maps to Astro's like so:\n\t\t\t\t// - `true` -> `\"always\"`\n\t\t\t\t// - `false` -> `\"never\"`\n\t\t\t\t// - `undefined` -> `\"ignore\"`\n\t\t\t\t// If config is set to \"ignore\", we leave it as undefined.\n\t\t\t\tif (_config.trailingSlash && _config.trailingSlash !== 'ignore') {\n\t\t\t\t\t// Otherwise, map it accordingly.\n\t\t\t\t\ttrailingSlash = _config.trailingSlash === 'always';\n\t\t\t\t}\n\n\t\t\t\tconst { routes: redirects = [], error } = getTransformedRoutes({\n\t\t\t\t\ttrailingSlash,\n\t\t\t\t\trewrites: [],\n\t\t\t\t\tredirects: getRedirects(routes, _config),\n\t\t\t\t\theaders: [],\n\t\t\t\t});\n\t\t\t\tif (error) {\n\t\t\t\t\tthrow new AstroError(\n\t\t\t\t\t\t`Error generating redirects: ${error.message}`,\n\t\t\t\t\t\terror.link ? `${error.action ?? 'More info'}: ${error.link}` : undefined,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tlet images: VercelImageConfig | undefined;\n\t\t\t\tif (imagesConfig) {\n\t\t\t\t\timages = {\n\t\t\t\t\t\t...imagesConfig,\n\t\t\t\t\t\tdomains:\n\t\t\t\t\t\t\timagesConfig.domains || _config.image.domains\n\t\t\t\t\t\t\t\t? [...(imagesConfig.domains ?? []), ...(_config.image.domains ?? [])]\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\tremotePatterns: [...(imagesConfig.remotePatterns ?? [])],\n\t\t\t\t\t};\n\t\t\t\t\tconst remotePatterns = _config.image.remotePatterns;\n\t\t\t\t\tfor (const pattern of remotePatterns) {\n\t\t\t\t\t\tif (isAcceptedPattern(pattern)) {","sourceCodeStart":583,"sourceCodeEnd":619,"githubUrl":"https://github.com/withastro/astro/blob/3578d45d34226d63cff3d261c971c221de6794d2/packages/integrations/vercel/src/index.ts#L583-L619","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Read the appended underlying `error.message` (and the \"More info\" link) — it names the exact offending redirect","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","Set `trailingSlash: 'ignore'` temporarily to see if the slash rule is what breaks the transform","Simplify the failing redirect to a static from/to pair, or move dynamic redirects into middleware"],"exampleFix":"// before\nredirects: [{ from: '/docs/**:rest', to: '/guides/:rest', status: 301 }],\n\n// after\nredirects: [{ from: '/docs/:rest(.*)', to: '/guides/:rest', status: 301 }],","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await build(); // or astro build via CLI\n} catch (e) {\n  if (e instanceof AstroError && e.message.startsWith('Error generating redirects')) {\n    // e.message embeds the underlying reason; inspect config.redirects\n  }\n  throw e;\n}","preventionTips":["Add new redirects one at a time and rebuild so the offending entry is obvious","Keep redirect `from` patterns simple and test them against Astro's docs-supported syntax","When changing trailingSlash, rebuild immediately to catch transform conflicts"],"tags":["vercel","redirects","build","routing"],"backgroundTag":"invalid-route-configuration","analyzedSha":"3578d45d34226d63cff3d261c971c221de6794d2","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}