BoundaryML/baml · error
{} {} Request options: {}
Error message
{} {}
Request options: {} What it means
For LLMResponse::LLMFailure(e), run_test_with_expr_events formats an error as '{code} {message}\n\nRequest options: {json}' where the request options are first passed through scrub_baml_options to redact secrets (api keys, headers) using the provided env vars. This surfaces the provider's HTTP error code and message plus a sanitized dump of the request options that caused it.
Source
Thrown at engine/baml-runtime/src/lib.rs:1072
None,
env_vars.clone(),
)
.await;
let res = response_res?;
let (_, llm_resp, val) = res
.event_chain()
.iter()
.last()
.context("Expected non-empty event chain")?;
if let Some(expr_tx) = expr_tx {
expr_tx.unbounded_send(vec![]).unwrap();
}
let complete_resp = match llm_resp {
LLMResponse::Success(complete_llm_response) => Ok(complete_llm_response),
LLMResponse::InternalFailure(e) => Err(anyhow::anyhow!("{}", e)),
LLMResponse::UserFailure(e) => Err(anyhow::anyhow!("{}", e)),
LLMResponse::Cancelled(e) => Err(anyhow::anyhow!("Cancelled: {}", e)),
LLMResponse::LLMFailure(e) => Err(anyhow::anyhow!({
let scrubbed_opts =
crate::redaction::scrub_baml_options(&e.request_options, &env_vars, false);
format!(
"{} {}\n\nRequest options: {}",
e.code,
e.message,
serde_json::to_string(&scrubbed_opts).unwrap_or_default()
)
})),
}?;
let test_constraints_result = if constraints.is_empty() {
TestConstraintsResult::empty()
} else {
match val {
Some(Ok(value)) => {
let value_with_constraints = value.0.map_meta(|m| m.1.clone());
evaluate_test_constraints(
¶ms,View on GitHub (pinned to bd85ce9dee)
Solutions
- Read the code and message: fix auth (401/403), model name (404), rate limits (429, add backoff), or request shape accordingly
- Inspect the redacted 'Request options' section to see exactly what was sent
- Verify env vars for keys/headers are set so the request is built correctly
- Check provider status pages if code is 5xx and retry later
Example fix
// before
{"model": "gpt-99-nonexistent", ...} // 404 LLMFailure
// after
{"model": "gpt-4o", ...} Defensive patterns
Strategy: try-catch
Try / catch
// Parse the 'code message' prefix to branch on HTTP status
let err = match run_test_with_expr_events(...).await {
Err(e) => e,
Ok(r) => return Ok(r),
};
if let Some(code) = parse_http_code(&err.to_string()) {
match code {
429 => schedule_backoff_and_retry(),
401 | 403 => eprintln!("fix credentials"),
_ => eprintln!("provider error {code}: {err}"),
}
} Prevention
- Monitor for 429s and add rate limiting/backoff to test suites
- Rotate and validate API keys regularly
- Read the redacted request options dump to catch malformed requests early
When it happens
Trigger: Running an expr-function test when the provider returns an HTTP error response that BAML maps to LLMResponse::LLMFailure; the formatted code/message/request options are raised as an anyhow error.
Common situations: 401/403 from bad API keys; 404 from a wrong model name; 429 rate limiting; 5xx provider outages; invalid request body rejected by the provider.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/c6dea4b526afe55b.
Report an issue: GitHub.