BoundaryML/baml · error · anyhow::Error
args must be a map
Error message
args must be a map
What it means
The public render_prompt entry point requires its `args` parameter (the variables exposed to the template) to be a BamlValue::Map. Any other BamlValue variant — list, string, null, etc. — is rejected immediately with this anyhow bail before any rendering happens.
Source
Thrown at engine/baml-lib/jinja-runtime/src/lib.rs:639
// minijinja_err += &format!("\n\ncaused by: {next_err:#}");
// err = next_err;
// }
// anyhow::bail!("Error occurred while rendering prompt: {minijinja_err}");
// }
// }
// }
pub fn render_prompt(
template: &str,
args: &BamlValue,
ctx: RenderContext,
template_string_macros: &[TemplateStringMacro],
ir: &IntermediateRepr,
env_vars: &HashMap<String, String>,
) -> anyhow::Result<RenderedPrompt> {
if !matches!(args, BamlValue::Map(_)) {
anyhow::bail!("args must be a map");
}
let eval_ctx = EvaluationContext::new(env_vars, false);
let minijinja_args: minijinja::Value = args.clone().to_minijinja_value(ir, &eval_ctx);
let default_role = ctx.client.default_role.clone();
let allowed_roles = ctx.client.allowed_roles.clone();
let remap_role = ctx.client.remap_role.clone();
let enum_values_by_name = ir
.walk_enums()
.map(|e| {
let enum_name = e.name().to_string();
let enum_values = e
.walk_values()
.map(|v| MinijinjaBamlEnumValue {
value: v.name().to_string(),
alias: v.alias(&eval_ctx).unwrap_or(None),
enum_name: enum_name.clone(),
})
.collect::<Vec<_>>();View on GitHub (pinned to bd85ce9dee)
Solutions
- Wrap template variables in a named map: {"var1": value1, "var2": value2} before calling render_prompt.
- If args come from JSON, ensure the top level is an object `{...}`, not an array or scalar.
- Check helper wrappers (render_chat, render_completion) to confirm they are passed a map, not raw values.
Example fix
// before
let args = BamlValue::List(vec![...]);
render_prompt(ctx, &args, ...)
// after
let args = BamlValue::Map(vec![("name".into(), BamlValue::String("world".into()))].into_iter().collect());
render_prompt(ctx, &args, ...) Defensive patterns
Strategy: type-guard
Validate before calling
// ensure args is a map/object before calling render_prompt
if (args === null || typeof args !== "object" || Array.isArray(args)) throw new Error("args must be a named map of template variables"); Type guard
function isArgsMap(v) { return v !== null && typeof v === "object" && !Array.isArray(v); } Try / catch
match render_prompt(ctx, &args, ...) { Err(e) if e.to_string().contains("args must be a map") => { /* fix caller */ }, Err(e) => return Err(e) } Prevention
- Always construct args as a named map/object of variables.
- When loading args from JSON, require a top-level object.
- Wrap args construction in a helper that enforces the map shape.
When it happens
Trigger: Calling render_prompt (directly or via render_chat/render_completion/render_image helpers) with args constructed as a non-map BamlValue, or passing null/None where a map of named template variables is expected.
Common situations: Programmatic/SDK use where args are built dynamically and end up as a list or scalar; forgetting to wrap variables in a named map; deserializing args from JSON that is an array rather than an object.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- unsupported pack target `{target}`. {err}
- Invalid argument: {name}
- Failed before LLM call: {message}
- {e}
- BamlError: BamlClientError: Something went wrong with the LL
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/d3e97fe556ed928b.
Report an issue: GitHub.