{"record":{"id":"46bfb7b1758b3a27","repo":"BoundaryML/baml","slug":"http-error-status-body","errorCode":null,"errorMessage":"HTTP error: {status} {body}","messagePattern":"HTTP error: (.+?) (.+?)","errorType":"exception","errorClass":"ApiError","httpStatus":null,"severity":"error","filePath":"engine/baml-runtime/src/tracingv2/publisher/publisher.rs","lineNumber":194,"sourceCode":"            }\n\n            // D) happy path: 2xx → attempt to parse into T\n            serde_json::from_slice::<TEndpoint::Response<'resp>>(&bytes)\n                .map_err(ApiError::Deserialize)\n        };\n\n        match timeout(timeout_duration, fut).await {\n            Ok(res) => res,\n            Err(_) => Err(ApiError::Timeout(timeout_duration)),\n        }\n    }\n}\n\n#[derive(thiserror::Error, Debug)]\npub enum ApiError {\n    #[error(\"Transport error: {0}\")]\n    Transport(reqwest::Error),\n    #[error(\"HTTP error: {status} {body}\")]\n    Http {\n        status: reqwest::StatusCode,\n        body: String,\n    },\n    #[error(\"Failed to deserialize response: {0}\")]\n    Deserialize(serde_json::Error),\n    #[error(\"Request timed out after {0:?}\")]\n    Timeout(Duration),\n}\n\nimpl TypeLookup for RuntimeAST {\n    fn type_lookup(&self, name: &str) -> Option<Arc<baml_rpc::BamlTypeId>> {\n        self.ast.type_lookup(name)\n    }\n\n    fn function_lookup(&self, name: &str) -> Option<Arc<baml_rpc::ast::tops::BamlFunctionId>> {\n        self.ast.function_lookup(name)\n    }","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-runtime/src/tracingv2/publisher/publisher.rs#L176-L212","documentation":"This is the Display message of ApiError::Http in the BAML trace publisher. It is thrown when the trace/collector HTTP API returned a response but with an error status code; the message carries the reqwest::StatusCode and the response body for diagnosis. The library throws it so the actual server-side rejection (auth, quota, bad payload) is surfaced with its body.","triggerScenarios":"The BAML collector endpoint returned a 4xx/5xx response to a trace publish or baml-src upload request: invalid or expired BAML_SECRET (401/403), rate limiting (429), server error (500), or malformed payload rejected by the API (400).","commonSituations":"Expired or wrong API key in BAML_SECRET, organization/project misconfiguration on the BAML dashboard, hitting rate limits with high trace volume, or the cloud service having an outage (5xx).","solutions":["Read the status and body embedded in the error to identify the server-side cause.","Check that BAML_SECRET is valid and has access to the project (re-generate the key).","Back off and retry on 429/5xx responses.","Check BAML cloud service status if 5xx persists."],"exampleFix":"// before\nmatch res.status() {\n    StatusCode::OK => parse(res),\n    _ => panic!(\"upload failed\"),\n}\n// after\nlet status = res.status();\nlet body = res.text().await?;\nif !status.is_success() {\n    return Err(ApiError::Http { status, body });\n}","handlingStrategy":"try-catch","validationCode":"// preflight key check\nres = requests.get(f\"{BAML_URL}/health\", headers={\"Authorization\": f\"Bearer {BAML_SECRET}\"})\nassert res.status_code in (200, 404), f\"collector returned {res.status_code}: {res.text[:200]}\"","typeGuard":"fn is_http_err(e: &ApiError) -> Option<(reqwest::StatusCode, &str)> {\n    if let ApiError::Http { status, body } = e { Some((*status, body)) } else { None }\n}","tryCatchPattern":"match publisher.publish(ev) {\n    Err(ApiError::Http { status, body }) if status == reqwest::StatusCode::UNAUTHORIZED => {\n        rotate_api_key();\n    }\n    Err(ApiError::Http { status, .. }) if status.is_server_error() || status == reqwest::StatusCode::TOO_MANY_REQUESTS => {\n        backoff_and_retry();\n    }\n    Err(e) => log::error!(\"publish failed: {e}\"),\n    Ok(_) => {}\n}","preventionTips":["Validate BAML_SECRET against the dashboard before deployment","Monitor for 429s and throttle trace volume","Alert on 5xx from the collector endpoint","Log status+body on every API failure"],"tags":["http","api","baml","tracing"],"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-14T05:17:10.506Z"}