{"record":{"id":"3077b8c918631fbc","repo":"jackwener/OpenCLI","slug":"gmail-operation-returned-malformed-json","errorCode":null,"errorMessage":"Gmail ${operation} returned malformed JSON","messagePattern":"Gmail (.+?) returned malformed JSON","errorType":"error_code","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/gmail/utils.js","lineNumber":112,"sourceCode":"    throw new AuthRequiredError(GMAIL_HOST, `Gmail ${operation} returned HTTP ${status}`);\n  }\n  if (status !== 200) {\n    throw new CommandExecutionError(`Gmail ${operation} returned HTTP ${status || 'unknown'}`);\n  }\n  if (entry?.responseBodyTruncated === true) {\n    throw new CommandExecutionError(`Gmail ${operation} response exceeded the browser capture limit`);\n  }\n  const body = entry?.responsePreview;\n  if (Array.isArray(body)) return body;\n  if (typeof body !== 'string') {\n    throw new CommandExecutionError(`Gmail ${operation} response body was unavailable`);\n  }\n  try {\n    const parsed = JSON.parse(body.replace(/^\\)\\]\\}'\\s*/, ''));\n    if (!Array.isArray(parsed)) throw new Error('not an array');\n    return parsed;\n  } catch {\n    throw new CommandExecutionError(`Gmail ${operation} returned malformed JSON`);\n  }\n}\n\nfunction addressRef(value) {\n  if (!Array.isArray(value)) return null;\n  const address = cleanString(value[1]);\n  if (!address.includes('@')) return null;\n  return { address, name: cleanString(value[2]) || null };\n}\n\nfunction senderFromSummary(message) {\n  return addressRef(Array.isArray(message) ? message[1] : null);\n}\n\nfunction labelIdsFromMessages(messages) {\n  return [...new Set((Array.isArray(messages) ? messages : [])\n    .flatMap((message) => Array.isArray(message?.[10]) ? message[10] : [])\n    .filter((label) => typeof label === 'string' && label.startsWith('^')))];","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/gmail/utils.js#L94-L130","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"// ensure the session is really signed in before automating\nconst html = await page.evaluate(\"() => document.body.innerText.slice(0, 500)\");\nif (/sign in|choose an account|loggen Sie sich/i.test(html)) {\n  throw new Error('Gmail session is logged out; complete sign-in first');\n}","typeGuard":"function isGmailArrayPayload(body) {\n  return Array.isArray(body);\n}","tryCatchPattern":"try {\n  result = await gmailSearch(query);\n} catch (error) {\n  if (String(error.message).includes('malformed JSON')) {\n    // Gmail served non-JSON (login page, error page, protocol change)\n    await page.reload(); // re-establish a clean session, then retry once\n    result = await gmailSearch(query);\n  } else throw error;\n}","preventionTips":["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."],"tags":["gmail","json","browser-bridge","malformed-response"],"backgroundTag":"malformed-json-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}