BoundaryML/baml · error · anyhow::Error
Failed to render template '{}': {}
Error message
Failed to render template '{}': {} What it means
BAML renders Jinja templates for prompt parts via minijinja. When tmpl.render(context) fails, the minijinja error is wrapped in this message with the template name. It means the template syntax parsed fine but execution failed — e.g. an undefined variable, a bad filter, or a runtime type error during rendering.
Source
Thrown at engine/baml-lib/baml-core/src/ir/ir_helpers/mod.rs:2091
})
.chain(std::iter::once(template_content.to_string()))
.collect::<Vec<_>>()
.join("\n");
// Use the shared environment (trim_blocks, lstrip_blocks, debug,
// null formatter, regex_match/sum filters) to match the prompt renderer.
let mut env = get_env();
env.add_template("__template__", &full_template)
.map_err(|e| anyhow::anyhow!("Failed to parse template '{}': {}", name, e))?;
let tmpl = env
.get_template("__template__")
.map_err(|e| anyhow::anyhow!("Failed to get template '{}': {}", name, e))?;
let context = minijinja::Value::from_serialize(&args_map);
let rendered = tmpl
.render(context)
.map_err(|e| anyhow::anyhow!("Failed to render template '{}': {}", name, e))?;
Ok(rendered)
}
}
#[cfg(test)]
mod render_template_tests {
use baml_types::TemplateStringRenderer;
use repr::make_test_ir;
use super::*;
#[test]
fn render_basic_template() {
let ir = make_test_ir(
r##"
template_string Greet(name: string) #"
Hello, {{ name }}!View on GitHub (pinned to bd85ce9dee)
Solutions
- Read the inner minijinja error after ': {}' — it names the exact variable/filter that failed.
- Verify every {{ var }} in the template exists in the args passed to the function.
- Replace unsupported Jinja2 filters/syntax with minijinja-compatible equivalents.
- Print or log args_map before rendering to confirm keys match template references.
Example fix
// before
{{ user.nmae | upper }}
// after
{{ user.name | upper }} Defensive patterns
Strategy: validation
Validate before calling
fn template_vars_ok(template: &str, args: &serde_json::Map<String, serde_json::Value>) -> bool {
// crude check: every {{ var }} referenced has a matching arg key
template.match_indices("{{").all(|(i, _)| {
let rest = &template[i + 2..];
let name: String = rest.chars().take_while(|c| !c.is_whitespace() && *c != '|' && *c != '}').collect();
name.is_empty() || args.contains_key(&name)
})
} Try / catch
match render_template(&name, &args) {
Ok(r) => r,
Err(e) if e.to_string().contains("Failed to render template") => {
eprintln!("render failed: {e:#}"); // inner error names the bad var/filter
fallback_template()
}
Err(e) => return Err(e),
} Prevention
- Cross-check every {{ var }} against the args you pass.
- Stick to minijinja-supported filters and syntax.
- Unit-test prompt templates with representative args.
When it happens
Trigger: Rendering a BAML prompt/partial template whose body references missing variables not present in args_map, applies an unknown filter, or performs an invalid operation (e.g. iterating a non-iterable) at render time.
Common situations: Typo in a variable name inside {{ }} blocks; using a Jinja filter not supported by minijinja; passing args whose shape doesn't match what the template expects; templates copied from Jinja2 docs using unsupported features.
Related errors
- Failed to get template '{}': {}
- Expected a statically defined string, not expression
- UnknownMethod
- TooManyArguments
- SyntaxError
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/c47e617113be9fe6.
Report an issue: GitHub.