{"record":{"id":"8d561c396dd3d4e5","repo":"BoundaryML/baml","slug":"json-serialization-error","errorCode":null,"errorMessage":"JSON serialization error: {}","messagePattern":"JSON serialization error: (.+?)","errorType":"exception","errorClass":"HttpError","httpStatus":null,"severity":"error","filePath":"engine/playground-server/src/api/errors.rs","lineNumber":33,"sourceCode":"    fn into_response(self) -> axum::response::Response {\n        // For IPC, keep it simple but preserve error chain information\n        let error_message = format!(\"{:#}\", self.0);\n\n        (\n            StatusCode::INTERNAL_SERVER_ERROR,\n            Json(json!({\n                \"error\": error_message,\n                \"type\": \"InternalError\"\n            })),\n        )\n            .into_response()\n    }\n}\n\n// Keep existing From implementation for backward compatibility\nimpl From<serde_json::Error> for HttpError {\n    fn from(err: serde_json::Error) -> Self {\n        HttpError(anyhow::anyhow!(\"JSON serialization error: {}\", err))\n    }\n}\n\n#[derive(Debug)]\npub enum ApiError {\n    NotFound(String),\n    BadRequest(String),\n    InternalError(String),\n    Unauthorized(String),\n}\n\nimpl IntoResponse for ApiError {\n    fn into_response(self) -> axum::response::Response {\n        let (status, message) = match self {\n            ApiError::NotFound(msg) => (StatusCode::NOT_FOUND, msg),\n            ApiError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg),\n            ApiError::InternalError(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg),\n            ApiError::Unauthorized(msg) => (StatusCode::UNAUTHORIZED, msg),","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/playground-server/src/api/errors.rs#L15-L51","documentation":"A From<serde_json::Error> impl in the playground server's error module converts any serde_json failure into an HttpError with message 'JSON serialization error'. It fires whenever request/response bodies fail to serialize or deserialize as JSON in the playground API.","triggerScenarios":"Serializing an API response whose types aren't JSON-representable (maps with non-string keys, NaN values), or deserializing a client request body that isn't valid JSON or doesn't match the expected schema.","commonSituations":"Client posting malformed JSON to playground endpoints; response payloads containing f64::NAN/Infinity; type changes in API structs breaking older clients; map keys that serde_json rejects.","solutions":["Validate the request body is well-formed JSON matching the endpoint schema","Check for NaN/Infinity or non-string map keys in values being serialized","Inspect the inner serde_json error for the exact field/path that failed","Fix the struct/serde attributes so all payload types are JSON-compatible"],"exampleFix":"// before: map with non-string key breaks serde_json\nHashMap<i64, Diagnosis> -> HttpError(JSON serialization error)\n// after\nHashMap<String, Diagnosis> // or serde(with = \"serialize_as_string_keys\")","handlingStrategy":"validation","validationCode":"try { JSON.parse(requestBody); } catch (e) { return 400; } // reject malformed JSON before hitting the API\n// and sanitize payload values:\nconst safe = JSON.parse(JSON.stringify(payload, (_, v) => Number.isNaN(v) ? null : v));","typeGuard":"function isJsonObject(v: unknown): v is Record<string, unknown> { return typeof v === 'object' && v !== null && !Array.isArray(v); }","tryCatchPattern":"match result { Err(HttpError(e)) if e.to_string().contains(\"JSON serialization error\") => respond(400, format!(\"invalid JSON: {e}\")), Err(e) => respond(500, e.to_string()), Ok(v) => respond(200, v) }","preventionTips":["Validate request bodies with a schema before processing","Avoid NaN/Infinity and non-string map keys in payloads","Keep serde derives in sync with API type changes","Log the inner serde_json error path for fast debugging"],"tags":["json","serialization","playground","rust","serde"],"backgroundTag":"json-serialization-failed","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}