{"record":{"id":"a30fa8c162a339d1","repo":"jackwener/OpenCLI","slug":"gmail-operation-requires-browser-response-inter","errorCode":null,"errorMessage":"Gmail ${operation} requires browser response interception","messagePattern":"Gmail (.+?) requires browser response interception","errorType":"error_code","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/gmail/utils.js","lineNumber":294,"sourceCode":"async function ensureGmailReady(page, account, operation) {\n  const currentUrl = typeof page.getCurrentUrl === 'function' ? await page.getCurrentUrl() : null;\n  if (!currentUrl?.startsWith(`${GMAIL_ORIGIN}/mail/u/${account}/`)) {\n    await page.goto(`${GMAIL_ORIGIN}/mail/u/${account}/#inbox`);\n  }\n  for (let attempt = 0; attempt < 60; attempt += 1) {\n    const ready = unwrapBrowserResult(await page.evaluate(`() => !!document.querySelector('input[name=\"q\"]')`), `${operation} readiness probe`);\n    if (ready === true) return;\n    await page.sleep(0.5);\n  }\n  throw new TimeoutError(`Gmail ${operation} page`, 30, 'The Gmail search surface did not become ready. Reload Gmail in the browser and retry.');\n}\n\nasync function installGmailCapture(page, account, endpoint, operation) {\n  if (\n    typeof page?.startNetworkCapture !== 'function'\n    || typeof page?.readNetworkCapture !== 'function'\n  ) {\n    throw new CommandExecutionError(`Gmail ${operation} requires browser response interception`);\n  }\n  if (!await page.startNetworkCapture(`/sync/u/${account}/i/${endpoint}`)) {\n    throw new CommandExecutionError(`Gmail ${operation} could not start browser response interception`);\n  }\n  await page.readNetworkCapture();\n}\n\nasync function waitGmailCaptures(page, endpoint, operation, timeoutSeconds = CAPTURE_WAIT_SECONDS) {\n  const deadline = Date.now() + timeoutSeconds * 1000;\n  let bodylessCaptureObserved = false;\n  // The bridge capture queue is request-oriented: reading it while a response\n  // is still in flight drains that request before its status/body arrive.\n  // Give Gmail's own action time to settle before the first read.\n  await page.sleep(endpoint === 'fd' ? 1 : 3);\n  while (Date.now() < deadline) {\n    const entries = await page.readNetworkCapture();\n    const endpointEntries = (Array.isArray(entries) ? entries : [])\n      .filter((entry) => String(entry?.url || '').includes(`/i/${endpoint}`));","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/gmail/utils.js#L276-L312","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before: raw puppeteer page lacks capture API\nconst page = await browser.newPage();\nawait listLabels(page, 0);\n// after: obtain the instrumented page from the library's helper\nconst page = await gmailBrowser.open({ capture: true });\nawait listLabels(page, 0);","handlingStrategy":"validation","validationCode":"if (typeof page?.startNetworkCapture !== 'function' || typeof page?.readNetworkCapture !== 'function') {\n  throw new Error('page wrapper must implement startNetworkCapture/readNetworkCapture before Gmail operations');\n}","typeGuard":"function hasNetworkCapture(page) {\n  return typeof page?.startNetworkCapture === 'function'\n    && typeof page?.readNetworkCapture === 'function';\n}","tryCatchPattern":"try {\n  await listLabels(page, 0);\n} catch (e) {\n  if (/requires browser response interception/.test(e.message)) {\n    console.error('Wrong page wrapper; use the library\\'s instrumented page');\n  } else throw e;\n}","preventionTips":["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"],"tags":["browser-automation","api-mismatch","gmail","network-capture"],"backgroundTag":"missing-api-method","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}