puppeteer/puppeteer · error · Error
HTTPRequest is missing _interceptionId needed for Fetch.fail
Error message
HTTPRequest is missing _interceptionId needed for Fetch.failRequest
What it means
Thrown by HTTPRequest._abort() (backing request.abort(errorReason)) when this._interceptionId is undefined. abort() issues Fetch.failRequest with the paused request's id; without interception enabled and the request actually paused, there is nothing to fail. Note this is the same _interceptionId guard as continue/respond.
Source
Thrown at packages/puppeteer-core/src/cdp/HTTPRequest.ts:294
.send('Fetch.fulfillRequest', {
requestId: this._interceptionId,
responseCode: status,
responsePhrase: STATUS_TEXTS[status],
responseHeaders: headersArray(responseHeaders),
body: parsedBody?.base64,
})
.catch(error => {
this.interception.handled = false;
return handleError(error, (this.frame() as any).logger);
});
}
async _abort(
errorReason: Protocol.Network.ErrorReason | null,
): Promise<void> {
this.interception.handled = true;
if (this._interceptionId === undefined) {
throw new Error(
'HTTPRequest is missing _interceptionId needed for Fetch.failRequest',
);
}
await this.#client
.send('Fetch.failRequest', {
requestId: this._interceptionId,
errorReason: errorReason || 'Failed',
})
.catch(error => {
return handleError(error, (this.frame() as any).logger);
});
}
}
View on GitHub (pinned to d484e21c17)
Solutions
- Enable interception with await page.setRequestInterception(true) first.
- Call abort() at most once per request and not alongside continue/respond.
- Filter out non-interceptable URLs (data:, memory cache) before aborting.
- Wrap abort() in try/catch to survive races where the request already completed.
Example fix
// before
page.on('request', req => {
if (/ads/.test(req.url())) req.abort(); // throws without interception
});
// after
await page.setRequestInterception(true);
page.on('request', req => {
if (/ads/.test(req.url())) {
req.abort('blockedbyclient').catch(() => {});
} else {
req.continue().catch(() => {});
}
}); Defensive patterns
Strategy: validation
Validate before calling
await page.setRequestInterception(true);
page.on('request', req => {
if (req.url().startsWith('data:')) return;
if (shouldBlock(req.url())) {
req.abort('blockedbyclient').catch(() => {});
} else {
req.continue().catch(() => {});
}
}); Type guard
function canAbort(req: HTTPRequest): boolean {
return !req.url().startsWith('data:') && !req.url().startsWith('blob:');
} Try / catch
try {
await request.abort('Failed');
} catch (e) {
if (e instanceof Error && /_interceptionId/.test(e.message)) {
// nothing to abort — ignore
} else throw e;
} Prevention
- Enable interception before aborting requests.
- Abort at most once per request and never alongside continue/respond.
- Exclude non-interceptable URLs from your abort rules.
When it happens
Trigger: Calling request.abort() in a request handler while setRequestInterception(true) was never called; aborting a data:/cached request that bypassed the Fetch domain; aborting after the request was already continued/responsed; calling abort in a listener that runs after another listener already handled the request.
Common situations: Ad-blocking style handlers attached without enabling interception; blocking rules applied too late (after load); multiple listeners racing to handle the same request.
Related errors
- HTTPRequest is missing _interceptionId needed for Fetch.cont
- HTTPRequest is missing _interceptionId needed for Fetch.fulf
- Launch aborted
- Response is missing for the interception
- Unknown CDP session with id ${id}
AI-assisted analysis of puppeteer/puppeteer@d484e21c17 (2026-08-12).
Data as JSON: /api/errors/9a7b7f4d9a9ad84b.
Report an issue: GitHub.