{"record":{"id":"0e4a6f6794576a44","repo":"jackwener/OpenCLI","slug":"label-returned-malformed-json-err-message-0e4a6f","errorCode":null,"errorMessage":"${label} returned malformed JSON: ${err?.message ?? err}","messagePattern":"(.+?) returned malformed JSON: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/goproxy/utils.js","lineNumber":90,"sourceCode":"        throw new EmptyResultError(label, `proxy.golang.org returned ${resp.status} for ${url}.`);\n    }\n    if (resp.status === 429) {\n        throw new CommandExecutionError(`${label} returned HTTP 429 (rate limited)`);\n    }\n    if (!resp.ok) {\n        throw new CommandExecutionError(`${label} returned HTTP ${resp.status}`);\n    }\n    return resp;\n}\n\nexport async function goproxyJson(url, label) {\n    const resp = await rawFetch(url, label);\n    let body;\n    try {\n        body = await resp.json();\n    }\n    catch (err) {\n        throw new CommandExecutionError(`${label} returned malformed JSON: ${err?.message ?? err}`);\n    }\n    return body;\n}\n\nexport async function goproxyText(url, label) {\n    const resp = await rawFetch(url, label);\n    return resp.text();\n}\n\n// Sort version tags by their numeric components, newest first. Pre-release tags\n// (anything after \"-\" that isn't a pure number) sort lower than the matching\n// release. Returns a new sorted array; non-tag inputs are dropped.\nexport function sortVersionsDescending(versions) {\n    return versions\n        .filter((v) => typeof v === 'string' && VERSION_TAG.test(v))\n        .map((v) => ({ v, parts: parseSemver(v) }))\n        .sort((a, b) => compareParts(b.parts, a.parts))\n        .map((entry) => entry.v);","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/goproxy/utils.js#L72-L108","documentation":"Thrown by goproxyJson when the HTTP response body from proxy.golang.org cannot be parsed as JSON. The Go module proxy normally serves strict JSON documents (@latest, @v/<ver>.info), so a parse failure means the endpoint returned HTML (error page, block page, captive portal) or a truncated body instead. The library wraps the underlying SyntaxError in a CommandExecutionError with the offending label for context.","triggerScenarios":"Calling goproxyJson(url, label) where fetch succeeded (2xx) but resp.json() throws: proxy returned an HTML error/interstitial page with 200 status, a captive portal or corporate proxy injected HTML, or the body was truncated mid-stream.","commonSituations":"Corporate proxies rewriting responses, DNS hijacking to a portal page, proxy.golang.org serving an unexpected maintenance page, network middleware corrupting the response, or pointing a custom command at a non-GOPROXY URL that returns HTML.","solutions":["Re-run the command to rule out a transient/truncated response","Verify network access: curl the same URL and inspect whether the body is JSON or HTML","Check for corporate proxies, VPNs, or captive portals intercepting traffic","If using a custom GOPROXY endpoint, confirm it actually implements the GOPROXY JSON protocol"],"exampleFix":"// before\nconst data = await goproxyJson(url, 'goproxy latest');\n// after\nlet data;\ntry { data = await goproxyJson(url, 'goproxy latest'); }\ncatch (e) { data = null; /* fall back or surface message */ }","handlingStrategy":"try-catch","validationCode":"// Preflight: confirm the endpoint serves JSON\nconst probe = await fetch(url);\nconst ct = probe.headers.get('content-type') || '';\nif (!ct.includes('json')) throw new Error('endpoint did not return JSON: ' + ct);","typeGuard":"function isJsonObject(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }","tryCatchPattern":"try {\n  const body = await goproxyJson(url, 'goproxy latest');\n} catch (err) {\n  // err is CommandExecutionError mentioning 'returned malformed JSON'\n  console.error('Proxy response was not JSON; check network/proxy interception.');\n  // optionally retry once or inspect via fetch + resp.text()\n}","preventionTips":["Check Content-Type before parsing JSON responses","Avoid relying on the CLI behind captive portals or rewriting corporate proxies","Retry once on transient malformed responses","Validate JSON shape before consuming fields"],"tags":["network","json","http","go"],"backgroundTag":"malformed-json-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}