{"record":{"id":"36ede38a9c8ef6fd","repo":"jackwener/OpenCLI","slug":"weread-official-apiname-returned-invalid-json","errorCode":null,"errorMessage":"weread-official ${apiName} returned invalid JSON","messagePattern":"weread-official (.+?) returned invalid JSON","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/weread-official/utils.js","lineNumber":117,"sourceCode":"    }\n    finally {\n        clearTimeout(timer);\n    }\n\n    if (!response.ok) {\n        throw new CommandExecutionError(\n            `weread-official ${apiName} HTTP ${response.status}`,\n            'Check WeRead gateway availability and that WEREAD_API_KEY is still valid.',\n        );\n    }\n\n    let payload;\n    try {\n        payload = await response.json();\n    }\n    catch (error) {\n        const detail = error instanceof Error ? error.message : String(error);\n        throw new CommandExecutionError(`weread-official ${apiName} returned invalid JSON`, detail);\n    }\n\n    if (payload && typeof payload === 'object' && payload.upgrade_info) {\n        const info = payload.upgrade_info;\n        const required = info?.required_version ?? info?.version ?? 'unknown';\n        const message = info?.message ?? 'WeRead skill version is outdated';\n        throw new CommandExecutionError(\n            `WeRead skill 需升级: ${message}. Required skill_version=${required}, current=${SKILL_VERSION}`,\n            'Pull the latest weread-skills.zip and bump SKILL_VERSION in clis/weread-official/utils.js.',\n        );\n    }\n\n    const errcode = Number(payload?.errcode ?? 0);\n    if (errcode !== 0) {\n        const errmsg = String(payload?.errmsg ?? 'unknown error');\n        if (AUTH_ERRCODES.has(errcode)) {\n            throw new AuthRequiredError(\n                WEREAD_DOMAIN,","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/weread-official/utils.js#L99-L135","documentation":"response.json() failed, meaning the gateway returned a body that is not valid JSON (e.g. an HTML error page, empty body, or a proxy block page). callGateway converts this to CommandExecutionError with the parser's message as detail.","triggerScenarios":"Gateway or an intermediary returning HTML (login page, 502 page, captcha challenge); truncated response; empty 200 response body; wrong content encoding.","commonSituations":"Captive portal or corporate proxy intercepting HTTPS; gateway outage serving an HTML maintenance page; hitting the wrong endpoint that returns a web page.","solutions":["Print the raw response body to see what was actually returned (likely HTML).","Check for proxy/VPN interception and disable it or set NO_PROXY.","Retry later if the gateway is serving a maintenance page.","Verify the request is going to the correct gateway URL."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const probe = await fetch(gatewayUrl, { method: 'HEAD' });\nconst ct = probe.headers.get('content-type') || '';\nif (!ct.includes('json')) throw new Error(`Gateway returned ${ct || 'no content-type'} — likely HTML/proxy interception`);","typeGuard":"const isBadJson = (e) => e instanceof CommandExecutionError && /invalid JSON/.test(e.message);","tryCatchPattern":"try {\n  return await callGateway(apiName, params);\n} catch (e) {\n  if (e instanceof CommandExecutionError && /invalid JSON/.test(e.message)) {\n    console.error('Response was not JSON — check for proxy/VPN interception or gateway outage, then retry');\n  }\n  throw e;\n}","preventionTips":["Disable VPN/proxy interception (add gateway domain to NO_PROXY)","Detect captive portals before long scripts run","Retry once on invalid JSON — outages are often transient","Log raw bodies when debugging by disabling error wrapping temporarily"],"tags":["json","http","response-parsing"],"backgroundTag":"invalid-json-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}