can1357/oh-my-pi · error · RequestInterceptionCleanupError
Failed to clear browser request interception after browser.r
Error message
Failed to clear browser request interception after browser.run
What it means
After a `browser.run` completes, the worker disables puppeteer request interception (`page.setRequestInterception(false)`) with a timeout. If disabling fails or times out, the cleanup error is rethrown as RequestInterceptionCleanupError so interception state never leaks silently into subsequent operations.
Source
Thrown at packages/coding-agent/src/tools/browser/tab-worker.ts:640
async cleanup() {
if (onDescriptor) Object.defineProperty(page, "on", onDescriptor);
else Reflect.deleteProperty(page, "on");
if (offDescriptor) Object.defineProperty(page, "off", offDescriptor);
else Reflect.deleteProperty(page, "off");
if (onceDescriptor) Object.defineProperty(page, "once", onceDescriptor);
else Reflect.deleteProperty(page, "once");
if (removeAllDescriptor) Object.defineProperty(page, "removeAllListeners", removeAllDescriptor);
else Reflect.deleteProperty(page, "removeAllListeners");
for (const handler of requestHandlers) Reflect.apply(off, page, ["request", handler]);
requestHandlers.length = 0;
try {
await withTimeout(
page.setRequestInterception(false),
REQUEST_INTERCEPTION_CLEANUP_TIMEOUT_MS,
"Timed out clearing browser request interception",
);
} catch (error) {
throw new RequestInterceptionCleanupError(
"Failed to clear browser request interception after browser.run",
{
error: error instanceof Error ? error.message : String(error),
},
);
}
},
};
}
function errorPayload(error: unknown): RunErrorPayload {
const recoverTab = error instanceof RequestInterceptionCleanupError || undefined;
if (error instanceof ToolAbortError) {
return { name: error.name, message: error.message, stack: error.stack, isToolError: false, isAbort: true };
}
if (error instanceof ToolError) {
return {
name: error.name,View on GitHub (pinned to 9690622007)
Solutions
- Inspect the wrapped `error` field: fix the underlying cause (typically an un-settled request handler in the run script).
- Ensure your interception handler never blocks indefinitely — always call request.continue()/abort()/fulfill().
- Retry browser.run; transient protocol stalls usually clear on a fresh run.
- If the browser is wedged, restart the browser/tab so a clean page is used for the next run.
Example fix
// before
await page.setRequestInterception(true);
page.on("request", req => doAsyncWork(req)); // may hang
// after
page.on("request", req => {
Promise.race([doAsyncWork(req), Bun.sleep(5000)]).finally(() => req.continue().catch(() => {}));
}); Defensive patterns
Strategy: try-catch
Try / catch
try {
await browser.run(script);
} catch (err) {
if (err instanceof RequestInterceptionCleanupError) {
logger.warn("interception cleanup failed", { cause: err.data?.error });
await restartBrowser(); // clear wedged state
} else throw err;
} Prevention
- Always settle request handlers with continue/abort/fulfill, even on error paths
- Never await unbounded work inside an interception handler
- Wrap handler bodies in a timeout
When it happens
Trigger: A page stuck in a long-running request handler/puppeteer request-interception callback while cleanup tries to disable interception; protocol stall between worker and Chromium exceeding REQUEST_INTERCEPTION_CLEANUP_TIMEOUT_MS.
Common situations: Scripts that block requests but hang a handler (e.g. awaiting a slow fetch inside the intercept handler); a wedged or overloaded Chromium; attached browser with pending network traffic.
Related errors
- Timed out after ${timeoutMs}ms closing ${tab.kindTag} browse
- tab.goto(${JSON.stringify(url)}) timed out after ${budgetBou
- GitCommandError: git worktree prune failed (incl. 124 timeou
- timed out: {command}
- AnthropicConnectionTimeoutError
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/e7779af9d60592b3.
Report an issue: GitHub.