{"record":{"id":"1f8117bd2fa0fb63","repo":"BoundaryML/baml","slug":"failed-before-llm-call-message","errorCode":null,"errorMessage":"Failed before LLM call: {message}","messagePattern":"Failed before LLM call: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-runtime/src/internal/llm_client/mod.rs","lineNumber":205,"sourceCode":"            Self::UserFailure(message) => {\n                write!(f, \"Failed before LLM call (user error): {message}\")\n            }\n            Self::InternalFailure(message) => write!(f, \"Failed before LLM call: {message}\"),\n            Self::Cancelled(message) => write!(f, \"Operation cancelled: {message}\"),\n        }\n    }\n}\n\nimpl LLMResponse {\n    pub fn content(&self) -> Result<&str> {\n        match self {\n            Self::Success(response) => Ok(&response.content),\n            Self::LLMFailure(failure) => Err(anyhow::anyhow!(\"LLM call failed: {failure:?}\")),\n            Self::UserFailure(message) => Err(anyhow::anyhow!(\n                \"Failed before LLM call (user error): {message}\"\n            )),\n            Self::InternalFailure(message) => {\n                Err(anyhow::anyhow!(\"Failed before LLM call: {message}\"))\n            }\n            Self::Cancelled(message) => Err(anyhow::anyhow!(\"Operation cancelled: {message}\")),\n        }\n    }\n}\n\n#[derive(Debug, Clone, Serialize, PartialEq)]\npub struct LLMErrorResponse {\n    pub client: String,\n    pub model: Option<String>,\n    pub prompt: RenderedPrompt,\n    pub request_options: BamlMap<String, serde_json::Value>,\n    #[cfg_attr(target_arch = \"wasm32\", serde(skip_serializing))]\n    pub start_time: web_time::SystemTime,\n    pub latency: web_time::Duration,\n\n    // Short error message\n    pub message: String,","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-runtime/src/internal/llm_client/mod.rs#L187-L223","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the embedded {message} to identify the pre-call failure (most often prompt rendering).","Fix the underlying prompt/param problem: check variable names, Jinja syntax, and that all required params are supplied to the BAML function call.","Check function failure with on_error / FunctionFailure instead of calling content() directly, so failure details reach your handler.","Verify your BAML clients and prompts compile with `baml-cli dev` — IR errors here surface as InternalFailure."],"exampleFix":"// before\nlet text = response.content()?; // panics into anyhow: Failed before LLM call: ...\n// after\nmatch response {\n    LLMResponse::Success(r) => Ok(r.content.clone()),\n    other => Err(anyhow::anyhow!(\"LLM unavailable: {other:?}\")),\n}","handlingStrategy":"try-catch","validationCode":"// Validate prompt inputs before calling the BAML function\nfn validate_params(params: &serde_json::Map<String, serde_json::Value>, required: &[&str]) -> Result<(), String> {\n    required.iter().find(|k| !params.contains_key(**k))\n        .map(|k| format!(\"missing param: {k}\"))\n        .map_or(Ok(()), Err)\n}","typeGuard":"fn has_content(resp: &LLMResponse) -> bool {\n    matches!(resp, LLMResponse::Success(_))\n}","tryCatchPattern":"match llm_response.content() {\n    Ok(c) => process(c),\n    Err(e) if e.to_string().starts_with(\"Failed before LLM call\") => {\n        log::error!(\"pre-call failure: {e:#}\");\n        fallback()\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Run `baml-cli dev` in CI so prompt/IR errors are caught before runtime.","Always check the response variant (FunctionSuccess vs FunctionFailure) before accessing content().","Keep template variables in sync with function params; use typed BAML clients from codegen."],"tags":["llm","rust","prompt-rendering","internal-failure"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}