BoundaryML/baml · error · ApiError
HTTP error: {status} {body}
Error message
HTTP error: {status} {body} What it means
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.
Source
Thrown at engine/baml-runtime/src/tracingv2/publisher/publisher.rs:194
}
// D) happy path: 2xx → attempt to parse into T
serde_json::from_slice::<TEndpoint::Response<'resp>>(&bytes)
.map_err(ApiError::Deserialize)
};
match timeout(timeout_duration, fut).await {
Ok(res) => res,
Err(_) => Err(ApiError::Timeout(timeout_duration)),
}
}
}
#[derive(thiserror::Error, Debug)]
pub enum ApiError {
#[error("Transport error: {0}")]
Transport(reqwest::Error),
#[error("HTTP error: {status} {body}")]
Http {
status: reqwest::StatusCode,
body: String,
},
#[error("Failed to deserialize response: {0}")]
Deserialize(serde_json::Error),
#[error("Request timed out after {0:?}")]
Timeout(Duration),
}
impl TypeLookup for RuntimeAST {
fn type_lookup(&self, name: &str) -> Option<Arc<baml_rpc::BamlTypeId>> {
self.ast.type_lookup(name)
}
fn function_lookup(&self, name: &str) -> Option<Arc<baml_rpc::ast::tops::BamlFunctionId>> {
self.ast.function_lookup(name)
}View on GitHub (pinned to bd85ce9dee)
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.
Example fix
// before
match res.status() {
StatusCode::OK => parse(res),
_ => panic!("upload failed"),
}
// after
let status = res.status();
let body = res.text().await?;
if !status.is_success() {
return Err(ApiError::Http { status, body });
} Defensive patterns
Strategy: try-catch
Validate before calling
// preflight key check
res = requests.get(f"{BAML_URL}/health", headers={"Authorization": f"Bearer {BAML_SECRET}"})
assert res.status_code in (200, 404), f"collector returned {res.status_code}: {res.text[:200]}" Type guard
fn is_http_err(e: &ApiError) -> Option<(reqwest::StatusCode, &str)> {
if let ApiError::Http { status, body } = e { Some((*status, body)) } else { None }
} Try / catch
match publisher.publish(ev) {
Err(ApiError::Http { status, body }) if status == reqwest::StatusCode::UNAUTHORIZED => {
rotate_api_key();
}
Err(ApiError::Http { status, .. }) if status.is_server_error() || status == reqwest::StatusCode::TOO_MANY_REQUESTS => {
backoff_and_retry();
}
Err(e) => log::error!("publish failed: {e}"),
Ok(_) => {}
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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).
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Transport error: {0}
- LLM client error: {message}
- baml.fetch_as: HTTP request failed: HTTP {} Body: {} at {:?}
- baml.fetch_as: expected url to be a string, got {}
- baml.fetch_as: expected method to be a valid HTTP method, go
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/46bfb7b1758b3a27.
Report an issue: GitHub.