{"record":{"id":"e2b352d965f8a104","repo":"BoundaryML/baml","slug":"failed-to-parse-response-url-status-status-body-body-error","errorCode":null,"errorMessage":"Failed to parse response: {url}. Status: {status}\nBody: {body} \nError: {:?}","messagePattern":"Failed to parse response: (.+?)\\. Status: (.+?)\nBody: (.+?) \nError: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-runtime/src/tracing/api_wrapper/mod.rs","lineNumber":157,"sourceCode":"            .json(body)\n            .bearer_auth(&self.api_key)\n            .build()?;\n\n        let Ok(res) = self.client.execute(req).await else {\n            return Err(anyhow::anyhow!(\"Failed to fetch: {url}\"));\n        };\n        let status = res.status();\n        let body = res.text().await?;\n\n        if !status.is_success() {\n            return Err(anyhow::anyhow!(\n                \"Failed to submit BAML log: {url}. Status: {status}\\nBody: {body}\"\n            ));\n        }\n\n        match serde_json::from_str::<T>(&body) {\n            Ok(v) => Ok(v),\n            Err(e) => Err(anyhow::anyhow!(\n                \"Failed to parse response: {url}. Status: {status}\\nBody: {body} \\nError: {:?}\",\n                e\n            )),\n        }\n    }\n}\n\n#[derive(Deserialize)]\nstruct LogResponse {\n    #[allow(dead_code)]\n    status: Option<String>,\n    #[allow(dead_code)]\n    message: Option<String>,\n}\n\nimpl BoundaryAPI for CompleteAPIConfig {\n    async fn check_cache(\n        &self,","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-runtime/src/tracing/api_wrapper/mod.rs#L139-L175","documentation":"Thrown by the BAML runtime's tracing HTTP client after submitting a BAML log event. The POST completed (a status was received) but `serde_json::from_str::<T>` could not deserialize the response body into the expected type. The message includes the URL, HTTP status, raw body, and serde error for diagnosis.","triggerScenarios":"Calling `post` in engine/baml-runtime/src/tracing/api_wrapper/mod.rs when the tracing/log collector endpoint returns a non-JSON body (HTML error page, empty body, plain text) or JSON whose shape does not match the expected generic type `T`.","commonSituations":"A proxy or corporate gateway intercepts the collector URL and returns an HTML auth page; the BAML server is down and returns a 502/503 text body; server and client BAML versions disagree on the response schema; the URL is misconfigured to point at a non-API endpoint.","solutions":["Inspect the URL, status, and body embedded in the message to see what actually came back.","Verify the BAML log/trace collector URL in configuration points at the correct JSON API endpoint, not a proxy or login page.","Check network setup (VPN, corporate proxy) that may intercept the request and return HTML.","Align BAML client and server versions so the response schema matches what the runtime expects.","Retry once connectivity is restored; a transient 5xx text response will parse as this error."],"exampleFix":"// before: pointing tracing at a webpage or proxy\nBAML_LOG_URL=https://internal-proxy.corp.com\n// after: point directly at the JSON collector endpoint\nBAML_LOG_URL=https://api.baml.example.com/v1/log","handlingStrategy":"try-catch","validationCode":"let resp_text = response.text()?;\nif resp_text.trim_start().parse::<serde_json::Value>().is_err() {\n    // endpoint did not return JSON; fix URL/connectivity before tracing calls\n}","typeGuard":"fn is_json_body(body: &str) -> bool {\n    serde_json::from_str::<serde_json::Value>(body).is_ok()\n}","tryCatchPattern":"match result {\n    Ok(v) => submit(v),\n    Err(e) if e.to_string().contains(\"Failed to parse response\") => {\n        log::warn!(\"trace collector returned non-JSON body; skipping trace upload: {e}\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Point the tracing endpoint at the real JSON API, not a proxy or login page.","Pin matching BAML client/server versions so response schemas agree.","Test collector connectivity from the deployment environment (VPN/proxy interference).","Treat trace upload failures as non-fatal: wrap in catch and continue."],"tags":["http","json","deserialization","tracing"],"backgroundTag":"invalid-json-response","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}