BoundaryML/baml · error · ApiError
Failed to deserialize response: {0}
Error message
Failed to deserialize response: {0} What it means
This is the Display message of ApiError::Deserialize in the BAML trace publisher. It is thrown when the response from the BAML tracing API could not be deserialized with serde_json — the request succeeded at the HTTP level but the body is not the JSON shape the client expects. Usually indicates an API/client version mismatch or a proxy/error page returning non-JSON.
Source
Thrown at engine/baml-runtime/src/tracingv2/publisher/publisher.rs:199
};
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)
}
fn baml_src_hash(&self) -> Option<String> {
self.ast.baml_src_hash()
}
}View on GitHub (pinned to bd85ce9dee)
Solutions
- Log the raw response body to see what was actually returned.
- Upgrade the BAML runtime and the BAML cloud/gateway to matching versions.
- Bypass or fix any proxy that rewrites responses (check for HTML error pages).
- Report schema mismatch to BAML if versions are current.
Example fix
// before
let resp: CheckResponse = serde_json::from_str(&body)?;
// after
let resp: CheckResponse = serde_json::from_str(&body)
.map_err(|e| { log::error!("unexpected collector body: {body}"); ApiError::Deserialize(e) })?; Defensive patterns
Strategy: try-catch
Validate before calling
// verify server/client compatibility
body = requests.get(f"{BAML_URL}/v1/check", headers=auth_headers).text
json.loads(body) # must not raise; HTML responses indicate a proxy issue Type guard
fn is_deserialize_err(e: &ApiError) -> bool { matches!(e, ApiError::Deserialize(_)) } Try / catch
match res {
Err(ApiError::Deserialize(e)) => {
log::error!("collector sent non-JSON/unexpected body: {e}");
// fall back: disable export or queue events for later
}
Err(e) => log::error!("publish failed: {e}"),
Ok(_) => {}
} Prevention
- Keep BAML runtime and cloud/gateway versions in sync
- Bypass proxies that rewrite API responses
- Log the raw response body on deserialize failures
- Pin gateway version when self-hosting
When it happens
Trigger: The collector responds with JSON that does not match the expected response struct (e.g. a check_response for source upload missing fields or changed schema), or a proxy/gateway returns an HTML error page, or an incompatible BAML server version is deployed.
Common situations: Self-hosted/older BAML gateway version returning an older response schema, a corporate proxy intercepting with an HTML auth page, or a new BAML client talking to an old backend.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- baml.json.serialize failed: {e:?}
- failed to serialize BAML bytecode: {e}
- type `{ty}` can't be passed through auto-CLI; deliver it via
- --json-args must be a JSON object, got: {json}
- missing required argument `{name}` (type: {ty}). pass it via
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/15656b5ecd47a237.
Report an issue: GitHub.