How to Check Request Interception State in Puppeteer
Puppeteer has no documented Page-level getter for request interception. Track setter calls yourself, and use request-level checks to avoid resolving a request twice.
Short answer: Puppeteer documents page.setRequestInterception(value) to turn interception on or off, but its current Page API reference does not document a Page-level getter for checking that setting. Track the value in your own application code whenever the setter succeeds. For a different question—whether one particular request has already been resolved—use that request’s isInterceptResolutionHandled() or interceptResolutionState() methods.
1. Track Page interception state in your application
Wrap calls to setRequestInterception() and keep the state in the same owner that controls the page. Set the flag after awaiting Puppeteer’s setter: if the setter rejects, your recorded state will not falsely claim that the change completed.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
const page = await browser.newPage();
let requestInterceptionEnabled = false;
async function setTrackedRequestInterception(page, enabled) {
await page.setRequestInterception(enabled);
requestInterceptionEnabled = enabled;
}
function isRequestInterceptionEnabled() {
return requestInterceptionEnabled;
}
await setTrackedRequestInterception(page, true);
console.log(isRequestInterceptionEnabled()); // true
await browser.close();
This is a minimal runnable ES module when Puppeteer is installed in the project. In a larger application, keep the flag alongside the page in a wrapper or page-owner object rather than in an unrelated module-global variable.
Keep the tracked value in sync
- Route every application call to
page.setRequestInterception()through the same wrapper. - Only update the flag after the awaited call succeeds.
- If the page is closed or replaced, discard its state along with that page.
- Account for
page.authenticate(): Puppeteer documents that authentication turns interception on behind the scenes. Record that setup in the same state owner; do not assume that disabling interception remains safe when authentication is configured.
The documented Page API surface provides the setter but no getter in the current reference. This conclusion is based on that documented surface, so check the reference for the Puppeteer version installed in your project when upgrading.
2. Distinguish Page configuration from request resolution
The tracked boolean answers: “Did my application successfully enable Page request interception?” It does not answer whether a specific request has already been continued, aborted, or answered. Puppeteer exposes request-level methods for that separate check.
page.on('request', async request => {
if (request.isInterceptResolutionHandled()) {
return;
}
// Do any asynchronous inspection before resolving the request.
const shouldBlock = new URL(request.url()).hostname === 'ads.example';
// Another registered handler may have resolved it while this handler awaited.
if (request.isInterceptResolutionHandled()) {
return;
}
if (shouldBlock) {
await request.abort();
} else {
await request.continue();
}
});
request.isInterceptResolutionHandled() is a guard for one HTTPRequest. request.interceptResolutionState() can also inspect the resolution state of that request. Neither is a Page-wide interception getter.
In async handlers, check before doing work and again after any await. Another registered handler may resolve the same request during that wait; attempting a second resolution can raise “Request is already handled!”.
3. Install a handler before page activity
With interception enabled, each request stalls until it is continued, answered, aborted, or completed from the browser cache. Enable interception and register a handler before navigation or other activity that creates requests. The resolution methods require interception and can throw immediately when it is not enabled.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
const page = await browser.newPage();
let interceptionEnabled = false;
async function setInterception(enabled) {
await page.setRequestInterception(enabled);
interceptionEnabled = enabled;
}
await setInterception(true);
page.on('request', async request => {
if (request.isInterceptResolutionHandled()) return;
await request.continue();
});
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
console.log({ interceptionEnabled });
await browser.close();
Choose one clear owner for request resolution. If multiple handlers are registered, each should follow the resolution guard pattern and account for asynchronous work.
4. Common errors and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
There is no page.isRequestInterceptionEnabled() |
The current documented Page API has a setter but does not show that getter. | Maintain an application-side flag around successful setter calls. |
| “Request is already handled!” | Two handlers attempted to resolve one request, often because one awaited work while another resolved it. | Check isInterceptResolutionHandled() before work and again after each asynchronous wait, then resolve only if still unhandled. |
| A request hangs or navigation never settles | An intercepted request was not continued, responded to, or aborted. | Install a handler before navigation and ensure every path resolves the request. Handle exceptions in asynchronous handlers so a thrown error does not leave work incomplete. |
continue(), abort(), or respond() throws |
Interception may not be enabled, or the request may already have been resolved. | Confirm the tracked Page state, then use the request-level handled check immediately before resolution. |
| The tracked flag says false after authentication is configured | page.authenticate() enables interception behind the scenes. |
Include authentication setup in the same state bookkeeping. Avoid assuming interception can be disabled while authentication is configured unless the installed version’s documentation or implementation confirms it. |
5. Reliability, performance, and version notes
- Reliability: Keep state per page, not as one process-wide boolean if several pages can have different configuration. Centralize setter calls so components cannot silently drift from the recorded value.
- Performance: Interception makes requests wait for resolution, so do as little work as possible in handlers and avoid unnecessary asynchronous delays. Puppeteer also notes that
page.authenticate()may affect performance because it enables interception internally. - Cache behavior: Puppeteer’s interception documentation allows a request to complete using the browser cache; do not treat every observed request as proof that a handler must run.
- Versioning: The research reference was for Puppeteer 25.12.0. API details can differ by release; consult the Page and request documentation matching your installed version.
6. Or skip the browser setup
If your goal is a clean screenshot rather than controlling Puppeteer’s network stack, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns an image or PDF, without setting up a browser or request handler. See the API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);
ScreenshotNeo accepts cookie and consent banners like a visitor and removes 60+ known consent platforms, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for 1,000 free screenshots a month, with no card required.
7. FAQ
Does the Page-level flag prove Puppeteer’s internal state?
It records successful changes made through your wrapper. It stays trustworthy only if all code that can change interception—including authentication setup—is represented in that same owner.
Can I inspect whether a particular request was resolved?
Yes. Use that request’s isInterceptResolutionHandled() or interceptResolutionState(); these methods do not report the Page’s interception setting.
Should I turn interception off after navigation?
Only if your application no longer needs it and the page’s other configuration permits it. In particular, account for page.authenticate() and verify behavior against your installed Puppeteer version.


