BoundaryML/baml · error · anyhow::Error
Template string '{}' expects {} arguments, but {} were provi
Error message
Template string '{}' expects {} arguments, but {} were provided What it means
When rendering a BAML template_string at runtime, `render_template` compares the number of supplied arguments with the template's declared inputs. Any mismatch (too few or too many) bails with this error naming the template, the expected count, and the actual count.
Source
Thrown at engine/baml-lib/baml-core/src/ir/ir_helpers/mod.rs:2041
item_type(&ir, &TypeIR::recursive_type_alias("JsonValue")).expect("should be Some");
let mut expected = TypeIR::recursive_type_alias("JsonValue");
expected.meta_mut().streaming_behavior.needed = true;
assert_eq!(ret, expected, "{ret} != {expected}");
}
}
/// Implementation of TemplateStringRenderer for IntermediateRepr.
/// This allows template_string calls to be resolved during test argument evaluation.
impl TemplateStringRenderer for IntermediateRepr {
fn render_template(&self, name: &str, args: &[serde_json::Value]) -> Result<String> {
// Find the template string definition
let template = self.find_template_string(name)?;
let template_content = template.template();
let template_params = template.inputs();
// Validate argument count
if args.len() != template_params.len() {
anyhow::bail!(
"Template string '{}' expects {} arguments, but {} were provided",
name,
template_params.len(),
args.len()
);
}
// Build the arguments map for minijinja
let mut args_map = serde_json::Map::new();
for (param, arg) in template_params.iter().zip(args.iter()) {
args_map.insert(param.name.clone(), arg.clone());
}
// Collect all template_strings as Jinja macro definitions, then chain
// the target template at the end. This matches how the prompt renderer
// in jinja-runtime injects macros.
let full_template = self
.walk_template_strings()View on GitHub (pinned to bd85ce9dee)
Solutions
- Pass exactly as many arguments as the template_string declares, in declaration order
- Update stale call sites after changing the template_string signature in .baml
- Compare the counts in the error message (expects N, provided M) to find what to add or remove
- If parameters became optional, still pass all declared inputs (pass null) since this renderer requires exact arity
Example fix
// before (.baml)
template_string Greet(name: string) #"Hello {{name}}"#
// render_template("Greet", []) // 0 of 1 args
// after (caller)
render_template("Greet", [json!("alice")]) Defensive patterns
Strategy: validation
Validate before calling
function assertTemplateArity(templateInputs: number, args: unknown[]): void {
if (args.length !== templateInputs) {
throw new Error(`Template expects ${templateInputs} arguments, got ${args.length}`);
}
} Try / catch
try {
const out = render_template(name, args);
} catch (e) {
if (String(e).includes('expects') && String(e).includes('arguments')) {
console.error('Align call-site args with the template_string inputs in .baml');
}
throw e;
} Prevention
- Update all template_string call sites when changing its input list
- Pass null for unused-but-declared inputs; this renderer requires exact arity
- Centralize template invocations in one helper that checks arity
- Keep generated test code in sync with template signatures
When it happens
Trigger: Calling TemplateStringRenderer::render_template(name, args) (used for template_string calls during test argument evaluation) with args.len() != number of inputs declared on the `template_string Name(a, b, ...)` in .baml.
Common situations: Adding a parameter to a template_string without updating call sites; passing a single object of args where positional values are expected; generated test code referencing an older template signature.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Missing required parameter: {param_name}
- Failed to parse template '{}': {}
- --json-args must be a JSON object, got: {json}
- {0}
- interned member `{name}` cannot be another member's child
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/1d23a0839c2f1485.
Report an issue: GitHub.