vercel/next.js · error · Error
Proxy request aborted [${request.method} ${request.url}]
Error message
Proxy request aborted [${request.method} ${request.url}] What it means
Thrown by the experimental testmode fetch interceptor when the test proxy responds with api 'abort' or 'unhandled' for a fetch. 'unhandled' means no registered mock matched the request URL/method; 'abort' is an explicit signal from the test to terminate the request. The message includes the original method and URL to help identify which fetch was unmocked.
Source
Thrown at packages/next/src/experimental/testmode/fetch.ts:125
'next-test-internal': '1',
},
next: {
// @ts-ignore
internal: true,
},
})
if (!resp.ok) {
throw new Error(`Proxy request failed: ${resp.status}`)
}
const proxyResponse = (await resp.json()) as ProxyResponse
const { api } = proxyResponse
switch (api) {
case 'continue':
return originalFetch(request)
case 'abort':
case 'unhandled':
throw new Error(
`Proxy request aborted [${request.method} ${request.url}]`
)
case 'fetch':
return buildResponse(proxyResponse)
default:
return api satisfies never
}
}
export function interceptFetch(originalFetch: Fetch) {
global.fetch = function testFetch(
input: FetchInputArg,
init?: FetchInitArg
): Promise<Response> {
// Passthrough internal requests.
// @ts-ignore
if (init?.next?.internal) {
return originalFetch(input, init)View on GitHub (pinned to 0ae8c72462)
Solutions
- Register an httpMockHandler (or use mocked async handler) that matches the exact URL/method of the failing fetch shown in the message.
- Loosen the mock matcher (wildcards, regex, ignore query params) so transient differences don't cause an unhandled result.
- Use `api: 'continue'` (passthrough) in the handler for fetches you intentionally want to hit the network during tests.
- Audit nested dependencies for surprise fetches and either mock or stub them at the module boundary.
Example fix
// before — no mock for /api/user
// fetch('/api/user') in server component -> abort
// after — register a matching mock
const handlers = [
{
url: '*/api/user',
method: 'GET',
handler: async () => Response.json({ id: 1, name: 'ada' }),
},
] Defensive patterns
Strategy: validation
Validate before calling
// Register a catch-all mock that returns 'continue' so unmocked fetches passthrough
const catchAll = { url: '*', handler: async () => ({ api: 'continue' }) }
// or assert all expected fetches are mocked before the test runs Try / catch
try {
await runServerAction()
} catch (e) {
if (/Proxy request aborted/.test(e.message)) {
console.error('Unmocked fetch detected:', e.message)
// register the missing mock and retry once
}
throw e
} Prevention
- Register mocks for every fetch the code path performs, including deep dependencies.
- Use a catch-all mock with `api: 'continue'` during development to avoid hard aborts.
- Match URLs loosely (wildcards, ignore query) to reduce spurious unhandled results.
- Audit nested deps for surprise network calls.
When it happens
Trigger: A server-side fetch() executes during a testmode test, the proxy receives it, but no httpMockHandler matches (or the handler returned 'unhandled'), so the proxy tells Next.js to abort. Triggered per-fetch in app-router or pages-router server code under testmode.
Common situations: Forgetting to mock a fetch that a deep dependency performs (analytics, auth lookup, telemetry); URL pattern mismatch between mock and actual call (trailing slash, query, absolute vs relative); or a mock handler timing out and the test aborting. Also when the test ends before all in-flight fetches resolve.
Related errors
- Proxy request failed: ${resp.status}
- Failed to fetch ${url}
- This is an internal example for testing the CLI.
- An instant() scope is already active. Nesting instant() call
- `forbidden()` is experimental and only allowed to be enabled
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/49772bacf2b10e07.
Report an issue: GitHub.