BoundaryML/baml · error
LLM call failed
Error message
LLM call failed: {failure:?} What it means
LLMResponse::content() extracts the text of a successful LLM response; if the runtime's result is an LLMFailure variant (the LLM call itself ran and failed — e.g. HTTP error, provider refusal, timeout), content() converts it into an anyhow error embedding the full debug dump of the LLMFailure struct. This error surfaces provider-side call failures to callers that only want the text content.
Solutions
- Inspect the embedded failure debug dump in the message for the provider's status/error body
- Match on the LLMResponse variant before calling content() and handle LLMFailure explicitly
- Check provider credentials (API keys) and model availability
- Add/review a retry policy in the BAML client config for transient provider failures
Example fix
// before
let text = response.content()?;
// after
let text = match response {
LLMResponse::Success(r) => &r.content,
LLMResponse::LLMFailure(f) => return Err(handle_llm_failure(f)), // inspect f.message/status
other => return Err(anyhow::anyhow!("unexpected response: {other:?}")),
}; Defensive patterns
Strategy: type-guard
Type guard
fn llm_content(r: &LLMResponse) -> Option<&str> {
match r { LLMResponse::Success(resp) => Some(&resp.content), _ => None }
} Try / catch
match llm_response {
LLMResponse::Success(r) => Ok(&r.content),
LLMResponse::LLMFailure(f) => Err(map_provider_failure(f)), // check status/body, maybe retry
other => Err(anyhow::anyhow!("not an LLM response: {other:?}")),
} Prevention
- Configure a retry policy for transient provider errors (429/5xx)
- Validate API keys and model names before deployment
- Always match on LLMResponse variants instead of unwrapping content()
- Log the failure debug dump to diagnose provider-side causes
When it happens
Trigger: Calling .content() (or code paths that unwrap content) on an LLMResponse that is LLMFailure — i.e. the provider returned an error status, invalid response, or the request failed after retries.
Common situations: Invalid API key leading to 401 from the provider; model name not available to the account; rate limits or provider outages; malformed requests rejected by the provider.
Related errors
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/722e220be3f61200.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-runtime/src/internal/llm_client/mod.rs:200
impl std::fmt::Display for LLMResponse {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Success(response) => write!(f, "{response}"),
Self::LLMFailure(failure) => write!(f, "LLM call failed: {failure:?}"),
Self::UserFailure(message) => {
write!(f, "Failed before LLM call (user error): {message}")
}
Self::InternalFailure(message) => write!(f, "Failed before LLM call: {message}"),
Self::Cancelled(message) => write!(f, "Operation cancelled: {message}"),
}
}
}
impl LLMResponse {
pub fn content(&self) -> Result<&str> {
match self {
Self::Success(response) => Ok(&response.content),
Self::LLMFailure(failure) => Err(anyhow::anyhow!("LLM call failed: {failure:?}")),
Self::UserFailure(message) => Err(anyhow::anyhow!(
"Failed before LLM call (user error): {message}"
)),
Self::InternalFailure(message) => {
Err(anyhow::anyhow!("Failed before LLM call: {message}"))
}
Self::Cancelled(message) => Err(anyhow::anyhow!("Operation cancelled: {message}")),
}
}
}
#[derive(Debug, Clone, Serialize, PartialEq)]
pub struct LLMErrorResponse {
pub client: String,
pub model: Option<String>,
pub prompt: RenderedPrompt,
pub request_options: BamlMap<String, serde_json::Value>,
#[cfg_attr(target_arch = "wasm32", serde(skip_serializing))]View on GitHub (pinned to bd85ce9dee)