{"record":{"id":"16c99955fb7d38c6","repo":"BoundaryML/baml","slug":"failed-to-submit-baml-log-url-status-status-body-body","errorCode":null,"errorMessage":"Failed to submit BAML log: {url}. Status: {status}\nBody: {body}","messagePattern":"Failed to submit BAML log: (.+?)\\. Status: (.+?)\nBody: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-runtime/src/tracing/api_wrapper/mod.rs","lineNumber":150,"sourceCode":"impl CompleteAPIConfig {\n    pub(self) async fn post<T: DeserializeOwned>(&self, path: &str, body: &Value) -> Result<T> {\n        let url = format!(\"{}/{}\", self.base_url, path);\n\n        let req = self\n            .client\n            .post(&url)\n            .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>,","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-runtime/src/tracing/api_wrapper/mod.rs#L132-L168","documentation":"After executing the POST in the tracing wrapper's `post` method, a non-success HTTP status is treated as a hard failure. The error includes the target URL, the HTTP status code, and the response body so the server-side rejection reason can be diagnosed.","triggerScenarios":"The tracing/log-submission endpoint responds with 4xx/5xx: invalid or expired API key (401/403), malformed payload rejected by the server (400/422), server error (5xx), or rate limiting (429).","commonSituations":"Rotated or missing BOUNDARY API key authenticating against the collector; posting logs to a URL for the wrong environment; collector service outage returning 502/503.","solutions":["Read the Status and Body in the error message to identify the server's rejection reason.","Check and refresh the BOUNDARY API key / authentication credentials (401/403 cases).","Retry later or check collector service health if the status is 5xx; fix the payload/URL if the status is 4xx.","Respect rate-limit headers and back off if the status is 429."],"exampleFix":"// before (stale credentials)\nclient.post(...).bearer_auth(&expired_api_key)  // 401 -> this error\n// after\n// regenerate the key in the dashboard\nclient.post(...).bearer_auth(&fresh_api_key)","handlingStrategy":"retry","validationCode":"// Before enabling submission, validate the API key against the collector health endpoint\ncurl -fsS -H \"Authorization: Bearer $BOUNDARY_API_KEY\" \"$BOUNDARY_URL/health\" || echo \"auth or endpoint problem\"","typeGuard":null,"tryCatchPattern":"// Rust: retry 5xx/429 only; fail fast on 4xx\nmatch wrapper.post(&url, &body).await {\n    Err(e) if is_retryable_status(&e) => retry_with_backoff(3),\n    Err(e) => { log::warn!(\"log submission rejected: {e}\"); Ok(default) },\n    ok => ok,\n}","preventionTips":["Rotate and verify API keys before deployment; a 401/403 in the error body means bad credentials.","Monitor collector health; 5xx statuses indicate server-side outages.","Parse the Body portion of the error message first — it usually names the exact rejection reason.","Back off on 429 rate-limit responses instead of retrying immediately."],"tags":["network","http-error-response","tracing","api"],"backgroundTag":"http-error-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"}