vercel/next.js · error · Error
API route returned a Response object in the Node.js runtime,
Error message
API route returned a Response object in the Node.js runtime, this is not supported. Please use `runtime: "edge"` instead: https://nextjs.org/docs/api-routes/edge-api-routes
What it means
Thrown by apiResolver() in development when a Pages Router API route (Node.js runtime) returns a Response object from its handler. The Node.js runtime for API routes does not support the web Response type; only the Edge runtime does. This is a dev-only guard (NODE_ENV !== 'production') to catch the mistake early.
Source
Thrown at packages/next/src/server/api-utils/node/api-resolver.ts:441
opts?: {
unstable_onlyGenerated?: boolean
}
) => revalidate(urlPath, opts || {}, req, apiContext)
const resolver = interopDefault(resolverModule)
let wasPiped = false
if (process.env.NODE_ENV !== 'production') {
// listen for pipe event and don't show resolve warning
res.once('pipe', () => (wasPiped = true))
}
const apiRouteResult = await resolver(req, res)
if (process.env.NODE_ENV !== 'production') {
if (typeof apiRouteResult !== 'undefined') {
if (apiRouteResult instanceof Response) {
throw new Error(
'API route returned a Response object in the Node.js runtime, this is not supported. Please use `runtime: "edge"` instead: https://nextjs.org/docs/api-routes/edge-api-routes'
)
}
console.warn(
`API handler should not return a value, received ${typeof apiRouteResult}.`
)
}
if (!externalResolver && !isResSent(res) && !wasPiped) {
console.warn(
`API resolved without sending a response for ${req.url}, this may result in stalled requests.`
)
}
}
} catch (err) {
await onError?.(
err,
{View on GitHub (pinned to 0ae8c72462)
Solutions
- Add `export const config = { runtime: 'edge' }` to the API route to switch to the Edge runtime.
- Or refactor the handler to use res.status().json()/res.send() instead of returning a Response.
- Move the logic into an App Router route handler (app/api/route.ts) which supports Response natively.
Example fix
// before (pages/api/edge-only.ts) - Node runtime returning Response
export default function handler(req, res) {
return Response.json({ ok: true }) // throws in dev
}
// after - declare edge runtime
export const config = { runtime: 'edge' }
export default function handler(req, res) {
return Response.json({ ok: true })
} Defensive patterns
Strategy: validation
Validate before calling
// Ensure the route declares the correct runtime before returning Response
function assertEdgeRuntime(config: { runtime?: string } | undefined) {
if (config?.runtime !== 'edge') throw new Error('Response requires runtime: edge')
} Type guard
function isEdgeRoute(config: any): boolean {
return config?.config?.runtime === 'edge'
} Prevention
- Add `export const config = { runtime: 'edge' }` to API routes that return Response.
- Prefer App Router route handlers for Response-based APIs.
- Run the dev server locally to catch this guard before deploy.
When it happens
Trigger: An API route file under pages/api/ without `export const config = { runtime: 'edge' }` returns `new Response(...)` or `Response.json(...)` from its handler. At line 440 the result is checked `instanceof Response` and the error is thrown.
Common situations: Copying an Edge API route snippet into a Node API route; using fetch-like patterns that return Response; upgrading code that assumed web Response works in Node runtime.
Related errors
- hmrRefresh can only be used in development mode. Please use
- Failed to fetch _devPagesManifest.json. Is something blockin
- Invalid redirect arguments. Please use a single argument URL
- Preview data is limited to 2KB currently, reduce how much da
- Invalid urlPath provided to revalidate(), must be a path e.g
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/ad6ca0a4e3d147d2.
Report an issue: GitHub.