{"record":{"id":"7a6acf904dec6f61","repo":"jackwener/OpenCLI","slug":"hf-paper-returned-malformed-json-err-message","errorCode":null,"errorMessage":"hf paper returned malformed JSON: ${err?.message ?? err}","messagePattern":"hf paper returned malformed JSON: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/hf/paper.js","lineNumber":58,"sourceCode":"        }\n        if (resp.status === 404) {\n            throw new EmptyResultError('hf paper', `Hugging Face has no paper page for \"${raw}\".`);\n        }\n        if (resp.status === 429) {\n            throw new CommandExecutionError(\n                'hf paper returned HTTP 429 (rate limited)',\n                'Hugging Face throttles unauthenticated traffic; wait a few seconds and retry.',\n            );\n        }\n        if (!resp.ok) {\n            throw new CommandExecutionError(`hf paper returned HTTP ${resp.status}`);\n        }\n        let body;\n        try {\n            body = await resp.json();\n        }\n        catch (err) {\n            throw new CommandExecutionError(`hf paper returned malformed JSON: ${err?.message ?? err}`);\n        }\n        if (!body || typeof body !== 'object' || !body.id) {\n            throw new EmptyResultError('hf paper', `Hugging Face returned no paper data for \"${raw}\".`);\n        }\n        const authors = Array.isArray(body.authors)\n            ? body.authors.map((a) => (typeof a === 'object' && a ? (a.name || a.fullname || '') : String(a))).filter(Boolean)\n            : [];\n        const aiKeywords = Array.isArray(body.ai_keywords) ? body.ai_keywords.join(', ') : '';\n        return [{\n            id: String(body.id),\n            title: String(body.title ?? ''),\n            authors: authors.join(', '),\n            publishedAt: String(body.publishedAt ?? '').slice(0, 10),\n            upvotes: body.upvotes != null ? Number(body.upvotes) : null,\n            aiKeywords,\n            summary: String(body.summary ?? ''),\n            aiSummary: String(body.ai_summary ?? ''),\n            url: `${endpoint}/papers/${body.id}`,","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/hf/paper.js#L40-L76","documentation":"CommandExecutionError(`hf paper returned malformed JSON: ${err?.message ?? err}`) thrown when resp.json() rejects — i.e. HF returned an OK (2xx) response whose body is not valid JSON (the wrapped message is the underlying SyntaxError from the JSON parser).","triggerScenarios":"The fetch succeeded with a 2xx status but the response body fails JSON.parse: an HTML error/interstitial page served with 200, a truncated response from an interrupted connection, or a proxy/CAPTCHA page injected into the body.","commonSituations":"A transparent proxy or captive portal returning HTML with status 200; HF returning a Cloudflare/challenge page; gzip/body truncation on flaky networks; a custom HF_ENDPOINT mirror that serves HTML instead of JSON.","solutions":["Inspect the actual body: curl -sS https://huggingface.co/api/papers/<id> | head — if it is HTML, a proxy/challenge page is intercepting the request.","Bypass or fix the proxy (check HTTP_PROXY/HTTPS_PROXY; disable intercepting middleboxes) so the raw JSON is delivered.","Retry — a truncated body on a flaky connection is usually transient.","If using a custom HF_ENDPOINT, verify the mirror returns JSON for /api/papers or revert to the default endpoint.","Wait out any Cloudflare/browser-challenge situation or query from a network/challenge-exempt IP."],"exampleFix":"// before (proxy injecting HTML)\nexport HTTPS_PROXY=http://intercept.corp:8080\nopencli hf paper 1706.03762   // malformed JSON\n// after\nunset HTTPS_PROXY   # or bypass the interceptor for huggingface.co\nopencli hf paper 1706.03762","handlingStrategy":"validation","validationCode":"// validate the endpoint actually returns JSON before invoking the CLI\nconst res = await fetch(`https://huggingface.co/api/papers/${id}`);\nconst text = await res.text();\nlet parsed;\ntry { parsed = JSON.parse(text); } catch { throw new Error('endpoint returned non-JSON body — check proxy/captive portal/HF_ENDPOINT'); }","typeGuard":"function isPaperPayload(v) {\n  return typeof v === 'object' && v !== null && 'id' in v && typeof v.id === 'string' && v.id.length > 0;\n}","tryCatchPattern":"try {\n  await run(['opencli', 'hf paper', id]);\n} catch (e) {\n  if (String(e.message).startsWith('hf paper returned malformed JSON:')) {\n    // fetch the URL manually, inspect the raw body (HTML? challenge page? truncation?), fix proxy, then retry\n  } else throw e;\n}","preventionTips":["Inspect the raw response body with curl when JSON parsing fails — HTML usually means a proxy/challenge page.","Bypass intercepting proxies or captive portals for huggingface.co.","Retry on flaky networks — truncated bodies are often transient.","Verify custom HF_ENDPOINT mirrors serve application/json.","Validate JSON parses (and has an .id field) before feeding results downstream."],"tags":["json","parse-error","huggingface","cli"],"backgroundTag":"malformed-json-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}