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

  1. Inspect the embedded failure debug dump in the message for the provider's status/error body
  2. Match on the LLMResponse variant before calling content() and handle LLMFailure explicitly
  3. Check provider credentials (API keys) and model availability
  4. 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

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)