jackwener/OpenCLI · error · CommandExecutionError
Gmail ${operation} returned malformed JSON
Error message
Gmail ${operation} returned malformed JSON What it means
This CommandExecutionError is thrown by parseJsonCapture when JSON.parse of the captured Gmail /sync body fails, or the parsed payload is not an array. Gmail prefixes its /sync JSON with the XSSI guard ')\]\}\'' which is stripped first; any remaining non-JSON content (HTML login/error page, partial body, protocol change) makes parsing fail. The library treats an unparseable capture as a failed command.
Source
Thrown at clis/gmail/utils.js:112
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) {
return addressRef(Array.isArray(message) ? message[1] : null);
}
function labelIdsFromMessages(messages) {
return [...new Set((Array.isArray(messages) ? messages : [])
.flatMap((message) => Array.isArray(message?.[10]) ? message[10] : [])
.filter((label) => typeof label === 'string' && label.startsWith('^')))];View on GitHub (pinned to 49907e53dc)
Solutions
- Reload Gmail in the browser and confirm the mailbox is fully signed in, then rerun the command.
- Retry — an intermittent partial body can parse-fail once and succeed on retry.
- Check whether the Gmail web UI itself works in the captured browser profile; update opencli if Gmail changed its payload format.
- Disable interfering proxies/extensions that could rewrite the /sync response.
Example fix
null
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure the session is really signed in before automating
const html = await page.evaluate("() => document.body.innerText.slice(0, 500)");
if (/sign in|choose an account|loggen Sie sich/i.test(html)) {
throw new Error('Gmail session is logged out; complete sign-in first');
} Type guard
function isGmailArrayPayload(body) {
return Array.isArray(body);
} Try / catch
try {
result = await gmailSearch(query);
} catch (error) {
if (String(error.message).includes('malformed JSON')) {
// Gmail served non-JSON (login page, error page, protocol change)
await page.reload(); // re-establish a clean session, then retry once
result = await gmailSearch(query);
} else throw error;
} Prevention
- Keep the browser profile signed in to Gmail and confirm the UI renders before automating.
- Disable proxies/extensions that can rewrite or inject into /sync responses.
- Update the CLI when Gmail rolls out format changes; malformed-JSON errors often mark a protocol shift.
- Handle it as retryable once, then surface it — repeated failures mean a session or format problem.
When it happens
Trigger: The /i/bv or /i/fd response body is not an array of JSON (Gmail served an HTML interstitial/sign-in page, an error payload, or a new protocol shape), or the body was cut in a way that broke JSON but was not flagged truncated.
Common situations: Gmail session half-logged-out serving redirect HTML, Gmail UI A/B rollout changing the /sync payload shape, proxy/captive portal injecting content, region-redirect pages.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Chess.com API returned malformed JSON for ${url}: ${error?.m
- coingecko returned malformed JSON: ${error?.message || error
- ${label} returned malformed JSON: ${err?.message ?? err}
- Gmail ${operation} response exceeded the browser capture lim
- Gmail ${operation} response body was unavailable
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3077b8c918631fbc.
Report an issue: GitHub.