{"record":{"id":"75bedbbf4cc93b0d","repo":"withastro/astro","slug":"forbiddenrewrite","errorCode":"ForbiddenRewrite","errorMessage":"You tried to rewrite the on-demand route '${from}' with the static route '${to}', when using the 'server' output. \n\nThe static route '${to}' is rendered by the component\n'${component}', which is marked as prerendered. This is a forbidden operation because during the build, the component '${component}' is compiled to an\nHTML file, which can't be retrieved at runtime by Astro.","messagePattern":"You tried to rewrite the on-demand route '(.+?)' with the static route '(.+?)', when using the 'server' output\\. \n\nThe static route '(.+?)' is rendered by the component\n'(.+?)', which is marked as prerendered\\. This is a forbidden operation because during the build, the component '(.+?)' is compiled to an\nHTML file, which can't be retrieved at runtime by Astro\\.","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/core/middleware/sequence.ts","lineNumber":66,"sourceCode":"\t\t\t\t\t\t\t\thandleContext.request.clone(),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst oldPathname = handleContext.url.pathname;\n\t\t\t\t\t\tconst pipeline: Pipeline = Reflect.get(handleContext, pipelineSymbol);\n\t\t\t\t\t\tconst { routeData, pathname } = await pipeline.tryRewrite(\n\t\t\t\t\t\t\tpayload,\n\t\t\t\t\t\t\thandleContext.request,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// This is a case where the user tries to rewrite from a SSR route to a prerendered route (SSG).\n\t\t\t\t\t\t// This case isn't valid because when building for SSR, the prerendered route disappears from the server output because it becomes an HTML file,\n\t\t\t\t\t\t// so Astro can't retrieve it from the emitted manifest.\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tpipeline.manifest.serverLike === true &&\n\t\t\t\t\t\t\thandleContext.isPrerendered === false &&\n\t\t\t\t\t\t\trouteData.prerender === true\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthrow new AstroError({\n\t\t\t\t\t\t\t\t...ForbiddenRewrite,\n\t\t\t\t\t\t\t\tmessage: ForbiddenRewrite.message(\n\t\t\t\t\t\t\t\t\thandleContext.url.pathname,\n\t\t\t\t\t\t\t\t\tpathname,\n\t\t\t\t\t\t\t\t\trouteData.component,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\thint: ForbiddenRewrite.hint(routeData.component),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcarriedPayload = payload;\n\t\t\t\t\t\thandleContext.request = newRequest;\n\t\t\t\t\t\thandleContext.url = new URL(newRequest.url);\n\t\t\t\t\t\thandleContext.params = getParams(routeData, pathname);\n\t\t\t\t\t\thandleContext.routePattern = routeData.route;\n\t\t\t\t\t\tsetOriginPathname(\n\t\t\t\t\t\t\thandleContext.request,\n\t\t\t\t\t\t\toldPathname,","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/core/middleware/sequence.ts#L48-L84","documentation":"Thrown during a rewrite inside sequenced middleware when an on-demand (SSR) route tries to rewrite to a prerendered (SSG) route while output is 'server'. Prerendered routes are emitted as static HTML files at build time and are not in the server manifest, so the runtime cannot render them on demand. The check requires serverLike === true, the source isPrerendered === false, and the target routeData.prerender === true.","triggerScenarios":"Calling next(rewritePayload) (or returning a rewrite) from an SSR page/middleware to a route that has `export const prerender = true`, in a project with output 'server'. The ForbiddenRewrite error names the from-URL, the to-URL, and the target component.","commonSituations":"Mixing prerendered and on-demand routes and using rewrites to navigate between them; marking a route prerender=true but linking to it dynamically; refactoring routing without considering prerender status.","solutions":["Make the target route server-rendered (remove `export const prerender = true`) so it exists in the server manifest.","Use a redirect (HTTP) to the static HTML file instead of an in-rewrite, if the static route must stay prerendered.","Reorganize routes so SSR-to-prerendered rewrites are unnecessary."],"exampleFix":"// before - target page has prerender = true, source is SSR\nreturn context.next('/static-page'); // ForbiddenRewrite\n\n// after - remove prerender from target, or use a redirect\nreturn context.redirect('/static-page');","handlingStrategy":"validation","validationCode":"// Verify target route is server-rendered before rewriting.\nconst pipeline = Reflect.get(context, pipelineSymbol);\nconst { routeData } = await pipeline.tryRewrite(target, context.request);\nif (pipeline.manifest.serverLike && routeData.prerender) {\n  // use redirect instead of rewrite\n  return context.redirect(target);\n}\nreturn context.next(target);","typeGuard":"function isRewritableTarget(routeData: { prerender?: boolean }, serverLike: boolean): boolean {\n  return !(serverLike && routeData.prerender === true);\n}","tryCatchPattern":"try {\n  return await context.next('/some-route');\n} catch (e) {\n  if (e instanceof Error && /forbidden operation/i.test(e.message)) {\n    return context.redirect('/some-route'); // static HTML exists\n  }\n  throw e;\n}","preventionTips":["Do not rewrite from SSR routes to prerendered routes; redirect instead.","Audit prerender flags when using rewrites across route types.","Keep dynamic redirect maps aware of prerender status."],"tags":["rewrite","prerender","ssr","routing","middleware"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}