{"record":{"id":"24a2d27391682a32","repo":"BoundaryML/baml","slug":"failed-before-llm-call-user-error-message","errorCode":null,"errorMessage":"Failed before LLM call (user error): {message}","messagePattern":"Failed before LLM call \\(user error\\): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-runtime/src/internal/llm_client/mod.rs","lineNumber":201,"sourceCode":"    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            Self::Success(response) => write!(f, \"{response}\"),\n            Self::LLMFailure(failure) => write!(f, \"LLM call failed: {failure:?}\"),\n            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,","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-runtime/src/internal/llm_client/mod.rs#L183-L219","documentation":"LLMResponse::content() also distinguishes failures that happened before any LLM call was made due to a user error; the UserFailure variant carries a message (typically from a BAML assert/raise, or argument/pre-call validation performed by user logic), and content() surfaces it verbatim as 'Failed before LLM call (user error)'. It separates user-induced pre-call failures from LLM/network failures.","triggerScenarios":"Calling .content() on an LLMResponse::UserFailure — produced when user-level checks (e.g. BAML raise/assert semantics or explicit user failure injection) short-circuit before the provider request is sent.","commonSituations":"BAML functions with assert/raise clauses whose conditions failed on the inputs; application logic deliberately marking the call as failed before sending; misconfigured prompts/parameters caught by pre-call validation.","solutions":["Read the embedded message — it states the user-level reason the call was aborted","Fix the inputs or the failing assert/raise condition in the BAML function before retrying","Handle the UserFailure variant explicitly instead of relying on content()","Review prompt/input validation logic that raises user failures"],"exampleFix":"// before\nlet text = response.content()?; // panics into generic user-error message\n// after\nif let LLMResponse::UserFailure(msg) = &response {\n    eprintln!(\"pre-call user failure: {msg}\"); // fix input/assert, then retry\n    return Err(UserFacingError(msg.clone()));\n}\nlet text = response.content()?;","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fn is_user_failure(r: &LLMResponse) -> Option<&str> {\n    match r { LLMResponse::UserFailure(m) => Some(m), _ => None }\n}","tryCatchPattern":"match llm_response {\n    LLMResponse::UserFailure(msg) => Err(UserError(msg.clone())), // fix inputs/asserts, no retry\n    other => other.content().map(|s| s.to_string()),\n}","preventionTips":["Check BAML assert/raise conditions against your inputs before invoking","Handle UserFailure distinctly from LLMFailure — it is not retryable","Validate prompt parameters and function arguments before the call","Surface the embedded user message to end users rather than a generic error"],"tags":["baml","user-error","pre-call-failure","error-handling"],"backgroundTag":"invalid-argument-value","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}