BoundaryML/baml · error
{e}
Error message
{e} What it means
During orchestration, BAML renders each strategy node's prompt before calling the LLM. If render_prompt fails, the node returns an InternalFailure LLMResponse plus this error whose message is the stringified prompt-rendering error ({e}). It means no HTTP request was made for this node — the failure happened entirely inside BAML's prompt pipeline.
Source
Thrown at engine/baml-runtime/src/internal/llm_client/orchestrator/call.rs:100
results.push((
cancel_scope,
LLMResponse::Cancelled("Operation cancelled".to_string()),
Some(Err(anyhow::anyhow!(
crate::errors::ExposedError::AbortError {
detailed_message: String::new()
}
))),
));
break;
}
result = async {
let prompt = match node.render_prompt(ir, prompt, ctx, params).await {
Ok(p) => p,
Err(e) => {
return Some((
node.scope,
LLMResponse::InternalFailure(e.to_string()),
Some(Err(anyhow::anyhow!(e.to_string()))),
));
}
};
let ctx = CtxWithHttpRequestId::from(ctx);
let response = node.single_call(&ctx, &prompt).await;
let parsed_response = match &response {
LLMResponse::Success(s) => {
if !node
.finish_reason_filter()
.is_allowed(s.metadata.finish_reason.as_ref())
{
let message = "Finish reason not allowed".to_string();
Some(Err(anyhow::anyhow!(
crate::errors::ExposedError::FinishReasonError {
prompt: prompt.to_string(),
raw_output: s.content.clone(),
detailed_message: message.clone(),View on GitHub (pinned to bd85ce9dee)
Solutions
- Read the embedded message {e}; it names the exact rendering problem.
- Fix the prompt template: correct variable names and Jinja syntax; ensure all ctx/params values are provided and correctly typed.
- Re-run `baml-cli dev` / regenerate the client so IR and generated code are in sync.
- Add an orchestration fallback strategy so other nodes can still serve the request if one fails to render.
Example fix
// before
b.baml_value("name", None)?; // render fails: missing param
// after
let ctx = runtime.ctx.create(Some(maplit::btreemap! {
"name" => "Alice".into(),
}))?; Defensive patterns
Strategy: validation
Validate before calling
// Ensure all template variables the prompt needs are present before invoking
fn ensure_vars(prompt_vars: &[&str], params: &HashMap<String, String>) -> Result<(), String> {
prompt_vars.iter().find(|v| !params.contains_key(**v))
.map(|v| format!("prompt variable '{v}' not supplied"))
.map_or(Ok(()), Err)
} Try / catch
match node_result {
Err(e) if e.to_string().contains("render") || e.to_string().contains("Missing") => {
log::error!("prompt render failed: {e}");
fallback_client_call()
}
other => other,
} Prevention
- Regenerate the BAML client after every .baml change so params match prompt templates.
- Use typed parameter structs from codegen instead of raw maps to catch missing fields at compile time.
- Keep a test that renders every production prompt with sample params.
When it happens
Trigger: orchestrate() -> node.render_prompt(ir, prompt, ctx, params) returns Err: bad Jinja/template syntax in the .baml prompt, missing or wrongly-typed parameters, or IR resolution failure for the referenced prompt/client.
Common situations: Renaming a function/parameter in .baml without updating callers; passing None for a required param; template referencing an undefined variable; BAML CLI version mismatch between generated client and runtime.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Failed before LLM call: {message}
- args must be a map
- {self}\n\nDetailed message: {detailed_message}
- Strategy provider is empty: {}
- Operation cancelled: {message}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/ae7ca7e86da90dc2.
Report an issue: GitHub.