{"record":{"id":"4834a1aec214cdab","repo":"jackwener/OpenCLI","slug":"mdn-search-returned-malformed-json-err-message","errorCode":null,"errorMessage":"mdn search returned malformed JSON: ${err?.message ?? err}","messagePattern":"mdn search returned malformed JSON: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/mdn/search.js","lineNumber":82,"sourceCode":"        }\n        catch (err) {\n            throw new CommandExecutionError(`mdn search request failed: ${err?.message ?? err}`);\n        }\n        if (resp.status === 429) {\n            throw new CommandExecutionError(\n                'mdn search returned HTTP 429 (rate limited)',\n                'MDN throttles bursty traffic; wait a few seconds and retry.',\n            );\n        }\n        if (!resp.ok) {\n            throw new CommandExecutionError(`mdn search returned HTTP ${resp.status}`);\n        }\n        let body;\n        try {\n            body = await resp.json();\n        }\n        catch (err) {\n            throw new CommandExecutionError(`mdn search returned malformed JSON: ${err?.message ?? err}`);\n        }\n        const docs = Array.isArray(body?.documents) ? body.documents : [];\n        if (!docs.length) {\n            throw new EmptyResultError('mdn search', `No MDN results matched \"${query}\" (locale ${locale}).`);\n        }\n        return docs.slice(0, limit).map((doc, i) => ({\n            rank: i + 1,\n            title: String(doc.title ?? ''),\n            slug: String(doc.slug ?? ''),\n            locale: String(doc.locale ?? locale),\n            summary: String(doc.summary ?? '').replace(/\\s+/g, ' ').trim(),\n            url: doc.mdn_url ? `${MDN_BASE}${doc.mdn_url}` : '',\n        }));\n    },\n});\n","sourceCodeStart":64,"sourceCodeEnd":98,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/mdn/search.js#L64-L98","documentation":"After a successful HTTP response, the adapter calls resp.json(). If the body is not valid JSON (HTML error page, truncated response, proxy interference), the JSON parse error is wrapped in this CommandExecutionError. It means the response succeeded at the HTTP layer but the payload is unusable.","triggerScenarios":"MDN returning an HTML error/captcha page with 200; truncated or corrupted responses; middle-boxes (proxies, captive portals) rewriting the body.","commonSituations":"Captive portal Wi-Fi injecting HTML; corporate proxies intercepting TLS; MDN API format changes; intermittent network truncation.","solutions":["Retry the request — could be transient corruption.","Verify what the endpoint actually returns: curl -s '<MDN search url>' and inspect the body.","Check for proxy/captive-portal interference and fix network path or TLS interception.","Update the adapter if MDN changed its API response format."],"exampleFix":"// before\nconst r = await mdnSearch({ query: 'flexbox' });\n// after\ntry {\n  const r = await mdnSearch({ query: 'flexbox' });\n} catch (e) {\n  if (String(e.message).includes('malformed JSON')) return retryOrFallback(e);\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { return await mdnSearch({ query }); } catch (e) {\n  if (String(e.message).includes('malformed JSON')) { return fallbackLocalDocs(query); }\n  throw e;\n}","preventionTips":["Verify endpoint payloads with curl when errors recur","Watch for proxies/captive portals rewriting HTTPS bodies","Retry once before failing — truncation is often transient","Keep the adapter updated for MDN API format changes"],"tags":["json","http","parse-error","network"],"backgroundTag":"malformed-json-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}