{"record":{"id":"e670aedacb63380f","repo":"jackwener/OpenCLI","slug":"gmail-operation-returned-http-status-unkn","errorCode":null,"errorMessage":"Gmail ${operation} returned HTTP ${status || 'unknown'}","messagePattern":"Gmail (.+?) returned HTTP (.+?)","errorType":"error_code","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/gmail/utils.js","lineNumber":97,"sourceCode":"  return decodeEntities(String(value || '')\n    .replace(/<style\\b[^>]*>[\\s\\S]*?<\\/style>/gi, ' ')\n    .replace(/<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi, ' ')\n    .replace(/<br\\s*\\/?\\s*>/gi, '\\n')\n    .replace(/<\\/(p|div|li|tr|h[1-6])>/gi, '\\n')\n    .replace(/<[^>]+>/g, ' '))\n    .replace(/[ \\t]+/g, ' ')\n    .replace(/ *\\n */g, '\\n')\n    .replace(/\\n{3,}/g, '\\n\\n')\n    .trim();\n}\n\nfunction parseJsonCapture(entry, operation) {\n  const status = Number(entry?.responseStatus || 0);\n  if (status === 401 || status === 403) {\n    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","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/gmail/utils.js#L79-L115","documentation":"For any captured Gmail response status that is not 200 (and not 401/403, which raise AuthRequiredError), parseJsonCapture throws CommandExecutionError. A missing/zero status (no capture at all) surfaces as 'HTTP unknown'. This signals the Gmail request itself failed at the HTTP level.","triggerScenarios":"Gmail returning 4xx/5xx (429 rate limit, 500 server error) for the captured operation, or the capture entry having no responseStatus so status coerces to 0 ('unknown') — e.g. request aborted before a response arrived.","commonSituations":"Hammering Gmail with many rapid queries and hitting 429; transient Google 5xx outages; navigation/page reload aborting the request so no status is captured; network interruptions mid-fetch.","solutions":["Retry after a short backoff, especially if the status was 429 or 5xx.","Reduce request frequency / lower the limit to avoid rate limiting.","If status is 'unknown', check that the page stays open and the request isn't aborted by navigation; re-run the command.","Inspect responsePreview/entry details in the capture log to identify the failing endpoint and status."],"exampleFix":"// before\nfor (const q of queries) await search(q); // bursts -> HTTP 429\n// after\nfor (const q of queries) {\n  await search(q);\n  await sleep(2000); // backoff between requests\n}","handlingStrategy":"retry","validationCode":"// No local pre-check possible; validate captures before parsing:\nif (!entry || !Number(entry.responseStatus)) {\n  throw new Error('capture has no HTTP status — request may have been aborted');\n}","typeGuard":null,"tryCatchPattern":"async function withRetry(fn, attempts = 3) {\n  for (let i = 0; i < attempts; i++) {\n    try { return await fn(); }\n    catch (e) {\n      const m = /HTTP (\\d+|unknown)/.exec(e.message);\n      const status = m && /^\\d+$/.test(m[1]) ? Number(m[1]) : 0;\n      const retryable = status === 429 || status >= 500 || status === 0;\n      if (!retryable || i === attempts - 1) throw e;\n      await sleep(2 ** i * 1000);\n    }\n  }\n}","preventionTips":["Add exponential backoff and jitter around Gmail operations.","Keep limits and query frequency modest to avoid 429s.","Keep the page open/stable so requests aren't aborted by navigation.","Alert on 5xx/unknown statuses from captures to catch outages or aborted requests early."],"tags":["http","network","gmail","rate-limit"],"backgroundTag":"http-5xx","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}