jackwener/OpenCLI · error · CommandExecutionError
Gmail ${operation} requires browser response interception
Error message
Gmail ${operation} requires browser response interception What it means
installGmailCapture requires the page object to expose startNetworkCapture and readNetworkCapture methods. If either is missing it throws this CommandExecutionError, because Gmail results are read from intercepted /sync network responses, which is impossible without browser response interception support. This is a capability check on the browser-driver wrapper, not a transient fault.
Source
Thrown at clis/gmail/utils.js:294
async function ensureGmailReady(page, account, operation) {
const currentUrl = typeof page.getCurrentUrl === 'function' ? await page.getCurrentUrl() : null;
if (!currentUrl?.startsWith(`${GMAIL_ORIGIN}/mail/u/${account}/`)) {
await page.goto(`${GMAIL_ORIGIN}/mail/u/${account}/#inbox`);
}
for (let attempt = 0; attempt < 60; attempt += 1) {
const ready = unwrapBrowserResult(await page.evaluate(`() => !!document.querySelector('input[name="q"]')`), `${operation} readiness probe`);
if (ready === true) return;
await page.sleep(0.5);
}
throw new TimeoutError(`Gmail ${operation} page`, 30, 'The Gmail search surface did not become ready. Reload Gmail in the browser and retry.');
}
async function installGmailCapture(page, account, endpoint, operation) {
if (
typeof page?.startNetworkCapture !== 'function'
|| typeof page?.readNetworkCapture !== 'function'
) {
throw new CommandExecutionError(`Gmail ${operation} requires browser response interception`);
}
if (!await page.startNetworkCapture(`/sync/u/${account}/i/${endpoint}`)) {
throw new CommandExecutionError(`Gmail ${operation} could not start browser response interception`);
}
await page.readNetworkCapture();
}
async function waitGmailCaptures(page, endpoint, operation, timeoutSeconds = CAPTURE_WAIT_SECONDS) {
const deadline = Date.now() + timeoutSeconds * 1000;
let bodylessCaptureObserved = false;
// The bridge capture queue is request-oriented: reading it while a response
// is still in flight drains that request before its status/body arrive.
// Give Gmail's own action time to settle before the first read.
await page.sleep(endpoint === 'fd' ? 1 : 3);
while (Date.now() < deadline) {
const entries = await page.readNetworkCapture();
const endpointEntries = (Array.isArray(entries) ? entries : [])
.filter((entry) => String(entry?.url || '').includes(`/i/${endpoint}`));View on GitHub (pinned to 49907e53dc)
Solutions
- Use the library's own browser page wrapper that implements startNetworkCapture/readNetworkCapture
- Check typeof page.startNetworkCapture === 'function' before calling Gmail operations
- Upgrade/align the browser helper module and the Gmail CLI to compatible versions
- If using Puppeteer directly, wrap the page with the library's network-capture instrumentation
Example fix
// before: raw puppeteer page lacks capture API
const page = await browser.newPage();
await listLabels(page, 0);
// after: obtain the instrumented page from the library's helper
const page = await gmailBrowser.open({ capture: true });
await listLabels(page, 0); Defensive patterns
Strategy: validation
Validate before calling
if (typeof page?.startNetworkCapture !== 'function' || typeof page?.readNetworkCapture !== 'function') {
throw new Error('page wrapper must implement startNetworkCapture/readNetworkCapture before Gmail operations');
} Type guard
function hasNetworkCapture(page) {
return typeof page?.startNetworkCapture === 'function'
&& typeof page?.readNetworkCapture === 'function';
} Try / catch
try {
await listLabels(page, 0);
} catch (e) {
if (/requires browser response interception/.test(e.message)) {
console.error('Wrong page wrapper; use the library\'s instrumented page');
} else throw e;
} Prevention
- Always create the page via the library's browser helper, not raw puppeteer.newPage()
- Pin compatible versions of the browser helper and this library
- Smoke-test typeof page.startNetworkCapture === 'function' at startup
When it happens
Trigger: Calling queryThreads, listLabels, or fetchThread with a page object whose wrapper does not implement startNetworkCapture or readNetworkCapture (e.g. a plain Puppeteer Page, a custom/driverless page shim, or an older browser-helper version).
Common situations: Passing a vanilla puppeteer page instead of the library's instrumented page wrapper; upgrading the browser helper and losing the capture API; mixing versions of the CLI and its browser module; stub page objects in scripts/tests.
Related errors
- Gmail ${operation} could not start browser response intercep
- Gmail ${operation} capture included a response without a bod
- Gmail ${operation} capture
- Gmail ${operation} requires native browser input
- Gmail ${operation} requires native browser keyboard input
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a30fa8c162a339d1.
Report an issue: GitHub.