claude-memory/graph/fixes/rust-reqwest-responsejson-yields-reqwesterror-not-serde-json-27a1f7.md
2026-02-28 10:53:52 -06:00

2.0 KiB

id type title tags importance confidence created updated relations
27a1f728-ec90-469c-a6ab-5644d333322f fix Rust: reqwest response.json() yields reqwest::Error, not serde_json::Error
rust
reqwest
serde
error-handling
serde_json
api
0.5 0.8 2026-02-28T04:58:15.771467+00:00 2026-02-28T16:53:52.215098+00:00
target type direction strength edge_id
4dc83eed-b0b1-4924-b82e-faf352426785 RELATED_TO incoming 0.9 f57f63b8-1a05-4645-a320-4b045569ff55
target type direction strength edge_id
3ecd877b-de73-4afd-b328-b3ee99f5a1e3 CAUSES incoming 0.9 08588ede-b8fa-4b19-9c7e-b513808fa2e7
target type direction strength edge_id
0e484de1-cb92-479c-95ec-06fa9e886c0c RELATED_TO incoming 0.7 67fc682d-2b46-43c8-b950-bd80147e0056
target type direction strength edge_id
23121a41-790a-4bf3-9a4b-39f299bc4015 RELATED_TO incoming 0.8 28a2471d-a080-4344-ab1e-5413df9e072c

Fix: reqwest JSON Error Type Mismatch

Problem

When using response.json::<T>().await, JSON decode failures produce a reqwest::Error — not a serde_json::Error. This means a custom error variant like:

#[derive(Debug, thiserror::Error)]
enum ApiError {
    #[error("Parse error: {0}")]
    Parse(#[from] serde_json::Error),
    // ...
}

...is unreachable if you only call response.json(). The #[from] impl exists but can never fire.

Fix

Decode manually in two steps so the serde_json::Error is produced directly:

let body = response.text().await.map_err(ApiError::Request)?;
let data = serde_json::from_str::<T>(&body).map_err(ApiError::Parse)?;

Why It Matters

This lets callers distinguish network errors (connection dropped, timeout) from JSON parse errors (malformed response, schema mismatch). With response.json(), both collapse into reqwest::Error and you lose that distinction.

Context

Caught during code review of api/client.rs in SBA Scout Rust rewrite Phase 2.