jackwener/OpenCLI · error · CommandExecutionError
Gmail ${operation} response body was unavailable
Error message
Gmail ${operation} response body was unavailable What it means
This CommandExecutionError is thrown by parseJsonCapture when the captured Gmail /sync response entry has neither a string responsePreview nor responseBodyTruncated === true — i.e. the entry reached the parser with a status of 200 but no usable body at all. waitGmailCaptures is supposed to filter such bodyless entries, so this indicates a race where the capture was read before the response body arrived or the bridge lost the body. The library throws rather than return partial data.
Source
Thrown at clis/gmail/utils.js:105
.replace(/\n{3,}/g, '\n\n')
.trim();
}
function parseJsonCapture(entry, operation) {
const status = Number(entry?.responseStatus || 0);
if (status === 401 || status === 403) {
throw new AuthRequiredError(GMAIL_HOST, `Gmail ${operation} returned HTTP ${status}`);
}
if (status !== 200) {
throw new CommandExecutionError(`Gmail ${operation} returned HTTP ${status || 'unknown'}`);
}
if (entry?.responseBodyTruncated === true) {
throw new CommandExecutionError(`Gmail ${operation} response exceeded the browser capture limit`);
}
const body = entry?.responsePreview;
if (Array.isArray(body)) return body;
if (typeof body !== 'string') {
throw new CommandExecutionError(`Gmail ${operation} response body was unavailable`);
}
try {
const parsed = JSON.parse(body.replace(/^\)\]\}'\s*/, ''));
if (!Array.isArray(parsed)) throw new Error('not an array');
return parsed;
} catch {
throw new CommandExecutionError(`Gmail ${operation} returned malformed JSON`);
}
}
function addressRef(value) {
if (!Array.isArray(value)) return null;
const address = cleanString(value[1]);
if (!address.includes('@')) return null;
return { address, name: cleanString(value[2]) || null };
}
function senderFromSummary(message) {View on GitHub (pinned to 49907e53dc)
Solutions
- Retry the command — the capture race is often transient.
- Update the browser bridge to a version that only exposes entries once status+body are complete.
- If it recurs, reload Gmail in the browser and rerun so the /sync request completes fully.
- Check network speed/proxy; a stalled /sync response can keep the body unavailable past the 10s wait.
Example fix
// user retry wrapper
try {
threads = await queryThreads(page, query, { limit: 20 });
} catch (error) {
if (String(error.message).includes('response body was unavailable')) {
await page.reload();
threads = await queryThreads(page, query, { limit: 20 });
} else throw error;
} Defensive patterns
Strategy: retry
Validate before calling
// confirm the page is settled before running commands
const url = await page.getCurrentUrl();
if (!String(url || '').startsWith('https://mail.google.com/mail/u/')) {
throw new Error('Gmail is not on the mailbox view; sign in / reload before running commands');
} Type guard
function hasBody(entry) {
return typeof entry?.responsePreview === 'string' || entry?.responseBodyTruncated === true;
} Try / catch
try {
result = await gmailSearch(query);
} catch (error) {
if (String(error.message).includes('response body was unavailable')) {
await sleep(2000); // let the in-flight /sync response settle
result = await gmailSearch(query); // single retry
} else throw error;
} Prevention
- Avoid triggering captures while Gmail is mid-navigation; let the page settle first.
- Retry once on this error — it is usually a capture race, not a data problem.
- Keep the browser bridge current; older versions expose entries before bodies arrive.
- On flaky networks, increase tolerances by rerunning rather than scripting rapid successive calls.
When it happens
Trigger: parseJsonCapture receives entry with responseStatus 200, responseBodyTruncated not true, and responsePreview being undefined/null/non-string — e.g. the settled re-read in waitGmailCaptures still returned an in-flight entry, or the bridge dropped the body of the /i/bv or /i/fd response.
Common situations: Slow Gmail /sync responses (large mailbox, slow network) racing the capture reads; browser bridge versions that emit status before body; capture queue drained mid-flight during pagination clicks.
Related errors
- Gmail ${operation} response exceeded the browser capture lim
- Gmail ${operation} returned malformed JSON
- Gmail batch-view response had an unexpected shape
- Gmail ${operation} could not find the search input
- Browser reported a completed download but the file is missin
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3d6cd069ca7a8816.
Report an issue: GitHub.