BoundaryML/baml · error

Failed before LLM call: {message}

Error message

Failed before LLM call: {message}

What it means

BAML wraps LLM client outcomes in an LLMResponse enum. The InternalFailure variant is produced when something went wrong inside BAML before any LLM API request was attempted (e.g. prompt rendering failed). When you call .content() on such a response, this anyhow error is raised carrying the internal message. It is not a model/provider error — the request never left the runtime.

Source

Thrown at engine/baml-runtime/src/internal/llm_client/mod.rs:205

            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))]
    pub start_time: web_time::SystemTime,
    pub latency: web_time::Duration,

    // Short error message
    pub message: String,

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Read the embedded {message} to identify the pre-call failure (most often prompt rendering).
  2. Fix the underlying prompt/param problem: check variable names, Jinja syntax, and that all required params are supplied to the BAML function call.
  3. Check function failure with on_error / FunctionFailure instead of calling content() directly, so failure details reach your handler.
  4. Verify your BAML clients and prompts compile with `baml-cli dev` — IR errors here surface as InternalFailure.

Example fix

// before
let text = response.content()?; // panics into anyhow: Failed before LLM call: ...
// after
match response {
    LLMResponse::Success(r) => Ok(r.content.clone()),
    other => Err(anyhow::anyhow!("LLM unavailable: {other:?}")),
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate prompt inputs before calling the BAML function
fn validate_params(params: &serde_json::Map<String, serde_json::Value>, required: &[&str]) -> Result<(), String> {
    required.iter().find(|k| !params.contains_key(**k))
        .map(|k| format!("missing param: {k}"))
        .map_or(Ok(()), Err)
}

Type guard

fn has_content(resp: &LLMResponse) -> bool {
    matches!(resp, LLMResponse::Success(_))
}

Try / catch

match llm_response.content() {
    Ok(c) => process(c),
    Err(e) if e.to_string().starts_with("Failed before LLM call") => {
        log::error!("pre-call failure: {e:#}");
        fallback()
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling LLMResponse::content() (via the public API or FunctionSuccess/FunctionFailure helpers) when the response is LLMResponse::InternalFailure, which the orchestrator produces when render_prompt fails for an orchestration node before single_call is made.

Common situations: Invalid template/Jinja expressions or missing params in the prompt; IR lookup failures after config edits; BAML internal invariant violations surfaced as stringified errors; passing a FunctionFailure result straight to content() without checking success.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/1f8117bd2fa0fb63. Report an issue: GitHub.