{"id":"440204f6a8272cb6","repo":"seanmonstar/reqwest","slug":"error-decoding-response-body","errorCode":null,"errorMessage":"error decoding response body","messagePattern":"error decoding response body","errorType":"exception","errorClass":"reqwest::Error","httpStatus":null,"severity":"error","filePath":"src/error.rs","lineNumber":353,"sourceCode":"    #[cfg(all(target_arch = \"wasm32\", any(target_os = \"unknown\", target_os = \"none\")))]\n    Status(StatusCode),\n    Body,\n    Decode,\n    Upgrade,\n}\n\n// constructors\n\npub(crate) fn builder<E: Into<BoxError>>(e: E) -> Error {\n    Error::new(Kind::Builder, Some(e))\n}\n\npub(crate) fn body<E: Into<BoxError>>(e: E) -> Error {\n    Error::new(Kind::Body, Some(e))\n}\n\npub(crate) fn decode<E: Into<BoxError>>(e: E) -> Error {\n    Error::new(Kind::Decode, Some(e))\n}\n\npub(crate) fn request<E: Into<BoxError>>(e: E) -> Error {\n    Error::new(Kind::Request, Some(e))\n}\n\npub(crate) fn dns<E: Into<BoxError>>(e: E) -> BoxError {\n    Box::new(DnsError { inner: e.into() })\n}\n\npub(crate) fn redirect<E: Into<BoxError>>(e: E, url: Url) -> Error {\n    Error::new(Kind::Redirect, Some(e)).with_url(url)\n}\n\npub(crate) fn status_code(\n    url: Url,\n    status: StatusCode,\n    #[cfg(not(all(target_arch = \"wasm32\", any(target_os = \"unknown\", target_os = \"none\"))))] reason: Option<hyper::ext::ReasonPhrase>,","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/seanmonstar/reqwest/blob/17e9bcb51c46edebfb6f5f2f5184b51dac4b3a7d/src/error.rs#L335-L371","documentation":"The `Kind::Decode` error from `error::decode(...)` (error.rs:352-354). It wraps failures while interpreting the response bytes — overwhelmingly `serde_json::from_slice` failing inside `.json::<T>()` (response.rs:272), or a hyper body decode error while reading the stream (client.rs:3129, response.rs:435).","triggerScenarios":"Calling `.json::<MyType>()` on a response whose body isn't valid JSON or doesn't match the type; the server returning HTML/text error pages with status 200; truncated body causing `serde_json` EOF; hyper failing to assemble/decode chunked frames.","commonSituations":"API returns `{\"error\": \"...\"}` while you deserialize into a success struct; gateway injects an HTML 502 page; `Content-Type` lies; partial response due to dropped connection so JSON is incomplete.","solutions":["Read `.text().await?` first and log it when decode fails, then parse manually to see the real payload.","Deserialize into a permissive enum/`serde_json::Value` to handle both success and error shapes.","Check `response.status()` and `Content-Type` before calling `.json()`.","Inspect `e.source()` for the exact `serde_json::Error` (line/column) or hyper decode error."],"exampleFix":"// before\nlet user: User = resp.json().await?; // decode error on HTML error page\n\n// after\nlet status = resp.status();\nlet text = resp.text().await?;\nif !status.is_success() {\n    anyhow::bail!(\"api error {status}: {text}\");\n}\nlet user: User = serde_json::from_str(&text)\n    .map_err(|e| anyhow::anyhow!(\"decode failed: {e}; body was: {text}\"))?","handlingStrategy":"try-catch","validationCode":"// Read body as text and inspect before deserializing.\nlet status = resp.status();\nlet ct = resp.headers().get(\"content-type\").cloned();\nlet text = resp.text().await?;\nif !status.is_success() { return Err(anyhow!(\"{status}: {text}\")); }\nif ct.map(|v| !v.to_string().contains(\"json\")).unwrap_or(true) {\n    return Err(anyhow!(\"expected json, got: {text}\"));\n}\n","typeGuard":"fn is_decode_error(e: &reqwest::Error) -> bool { e.is_decode() }\n","tryCatchPattern":"let value = match resp.json::<T>().await {\n    Ok(v) => v,\n    Err(e) if e.is_decode() => {\n        // e.url() / e.source() carry the body snippet and serde location\n        return Err(anyhow!(\"decode failed: {}\", e.source().map(|s| s.to_string()).unwrap_or_default()));\n    }\n    Err(e) => return Err(e.into()),\n};","preventionTips":["Check status and Content-Type before .json().\n        ","Deserialize into a wide type (serde_json::Value or an enum) when the API returns multiple shapes.","Log the raw body on decode failure once, then tighten the type."],"tags":["decode","serde","json","response"],"analyzedSha":"17e9bcb51c46edebfb6f5f2f5184b51dac4b3a7d","analyzedAt":"2026-08-06T01:23:05.134Z","schemaVersion":2}