jackwener/OpenCLI · error · TimeoutError
Gmail ${operation} page
Error message
Gmail ${operation} page What it means
ensureGmailReady polls for up to 60 attempts (0.5s each) waiting for the Gmail search input (input[name="q"]) to appear, then gives up and throws this TimeoutError with a nominal 30s budget. It means the Gmail web UI never rendered its search surface, so operations like queryThreads/listLabels/fetchThread cannot proceed safely. The library throws rather than returning partial or garbage results.
Source
Thrown at clis/gmail/utils.js:286
body: messageBody(record) || null,
attachments,
});
}
}
return messages;
}
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;View on GitHub (pinned to 49907e53dc)
Solutions
- Open the browser and confirm Gmail is actually logged in and fully loaded; re-authenticate if redirected to a login page
- Reload Gmail in the browser and retry the command (the error hint says exactly this)
- Ensure Gmail is set to the standard (not basic HTML) view at mail.google.com
- Increase the wait budget / run on a faster connection so rendering finishes within 30s
- Verify the correct account index (u/0, u/1, ...) matches the logged-in account
Example fix
// before: CLI fails immediately after fresh browser launch
await queryThreads(page, 'label:inbox');
// after: ensure session + readiness before the call
await page.goto('https://mail.google.com/mail/u/0/');
await page.waitForSelector('input[name="q"]', { timeout: 60000 });
await queryThreads(page, 'label:inbox'); Defensive patterns
Strategy: retry
Validate before calling
const ready = await page.evaluate('() => !!document.querySelector("input[name=q]")');
if (!ready) throw new Error('Run your browser, log into Gmail, and load the standard view first'); Try / catch
import { TimeoutError } from '<lib>';
try {
await queryThreads(page, 'in:unread');
} catch (e) {
if (e instanceof TimeoutError && /Gmail .* page/.test(e.message)) {
await page.reload();
await retry(queryThreads, [page, 'in:unread'], { retries: 2, backoffMs: 3000 });
} else throw e;
} Prevention
- Keep the Gmail session logged in and on the standard (non-HTML) view
- Reload Gmail and let it fully render before running commands
- Use a low-latency connection or raise the wait budget for slow networks
- Watch for login redirects/CAPTCHAs before automating
When it happens
Trigger: Calling queryThreads, listLabels, or fetchThread when the Gmail page never shows the search box within ~30s: Gmail loaded a login/redirect page, loaded a plain HTML fallback, the browser is hung, or the DOM never hydrated.
Common situations: Google session expired and Gmail redirects to accounts.google.com login; Gmail serves the basic HTML view which lacks input[name="q"]; slow network/proxy delays rendering beyond 30s; a CAPTCHA or 'unusual activity' interstitial is shown; wrong account index in the /mail/u/N URL.
Related errors
- Gmail ${operation} capture
- Unexpected 12306 probe: ${JSON.stringify(probe)}
- ChatGPT did not create a conversation URL after sending the
- ChatWise response
- Could not switch to ${wantModel} model
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/0398ef740fa0b410.
Report an issue: GitHub.