{"record":{"id":"4eab121617e5426b","repo":"tinyhumansai/openhuman","slug":"brave-returned-malformed-json-e","errorCode":null,"errorMessage":"Brave returned malformed JSON: {e}","messagePattern":"Brave returned malformed JSON: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/search/tools/brave.rs","lineNumber":108,"sourceCode":"        let detail = crate::openhuman::util::utf8_safe_prefix_at_byte_boundary(&body, 500);\n        tracing::warn!(\n            path = %path,\n            status = %status,\n            elapsed_ms = elapsed_ms as u64,\n            \"[brave] non-2xx response: {detail}\"\n        );\n        anyhow::bail!(\"Brave returned {status}: {detail}\");\n    }\n    tracing::debug!(\n        path = %path,\n        status = %status,\n        elapsed_ms = elapsed_ms as u64,\n        body_bytes = body.len(),\n        \"[brave] response ok\"\n    );\n    serde_json::from_str::<Value>(&body).map_err(|e| {\n        tracing::warn!(path = %path, \"[brave] JSON parse failed: {e}\");\n        anyhow::anyhow!(\"Brave returned malformed JSON: {e}\")\n    })\n}\n\nfn extract_query(args: &Value) -> anyhow::Result<String> {\n    let q = args\n        .get(\"query\")\n        .and_then(|v| v.as_str())\n        .ok_or_else(|| anyhow::anyhow!(\"Missing required parameter: query\"))?\n        .trim();\n    if q.is_empty() {\n        anyhow::bail!(\"Search query cannot be empty\");\n    }\n    Ok(q.to_string())\n}\n\nfn clamped_count(args: &Value, default: usize, max: usize) -> usize {\n    args.get(\"count\")\n        .and_then(|v| v.as_u64())","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/search/tools/brave.rs#L90-L126","documentation":"The Brave API returned a 2xx response whose body could not be parsed as JSON in `brave_get`. This fires when the response body is not valid JSON at all — an HTML error/consent page from an intercepting proxy, a truncated body from a connection cut mid-transfer, or a content-type mismatch. It is distinct from a schema drift (fields missing/renamed), which is reported as a shape-changed error instead.","triggerScenarios":"Thrown at src/openhuman/search/tools/brave.rs:108 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Reproduce the raw response externally: `curl -H 'X-Subscription-Token: <key>' 'https://api.search.brave.com/res/v1/web/search?q=test'` to inspect what is actually returned","If a corporate proxy intercepts TLS, configure the proxy or its CA in the core's TLS/proxy settings","Retry once — truncated bodies from interrupted transfers are often transient"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}