BoundaryML/baml · error · anyhow::Error
Predicate did not evaluate to a boolean
Error message
Predicate did not evaluate to a boolean
What it means
BAML constraint predicates (@assert/@check) are Jinja expressions rendered with 'this' bound to the value. The rendered output must be the string "true" or "false"; anything else raises this error. It ensures predicates are boolean expressions rather than arbitrary values.
Solutions
- Rewrite the predicate to be an explicit boolean comparison, e.g. {{ this.email != "" }}.
- Avoid predicates that return raw values; wrap them with a comparison or boolean cast.
- Test the expression renders exactly 'true' or 'false' for sample inputs.
Example fix
// before
@assert({{ this.items }})
// after
@assert({{ this.items|length > 0 }}) Defensive patterns
Strategy: validation
Validate before calling
fn is_boolean_predicate(expr: &str) -> bool {
// naive guard: reject bare 'this.x' returns without a comparison
let comparisons = [">", "<", ">=", "<=", "==", "!=", "&&", "||", "not ", "|length >"];
comparisons.iter().any(|c| expr.contains(c))
} Try / catch
match evaluate_predicate(&value, &expr) {
Ok(b) => b,
Err(e) if e.to_string().contains("did not evaluate to a boolean") => {
eprintln!("predicate '{}' must be a comparison, got a value", expr);
false
}
Err(e) => return Err(e),
} Prevention
- Always write predicates as explicit boolean comparisons.
- Never return a raw field or number from @assert/@check.
- Sanity-check that the expression renders to exactly 'true' or 'false'.
When it happens
Trigger: Calling evaluate_predicate (directly or via first_failing_assert_nested / run_user_checks) with a predicate expression whose rendered result is neither "true" nor "false" — e.g. {{ this.name }}, {{ this.items|length }}, or an expression producing an object.
Common situations: Writing an @assert that returns the field instead of a comparison; forgetting a comparison operator; using a filter that returns a number/string; predicates like {{ this.email }} intended as 'must be truthy'.
Related errors
- Error evaluating constraint
- {0}
- -32602
- all ingress capacities and the response reservation must be…
- artifact ` ` (kind = "pack") sets ` `, which is ignored for…
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/995feac143e5fe3d.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-lib/baml-core/src/ir/jinja_helpers.rs:92
// In rust string literals, `{` is escaped as `{{`.
// So producing the string `{{}}` requires writing the literal `"{{{{}}}}"`
let template = format!(r#"{{{{ {} }}}}"#, expression.0);
let args_dict = minijinja::Value::from_serialize(ctx);
Ok(env.render_str(&template, &args_dict)?)
}
// TODO: (Greg) better error handling.
// TODO: (Greg) Upstream, typecheck the expression.
pub fn evaluate_predicate(
this: &BamlValue,
predicate_expression: &JinjaExpression,
) -> Result<bool, anyhow::Error> {
let ctx: HashMap<String, minijinja::Value> =
HashMap::from([("this".to_string(), minijinja::Value::from_serialize(this))]);
match render_expression(predicate_expression, &ctx)?.as_ref() {
"true" => Ok(true),
"false" => Ok(false),
_ => Err(anyhow::anyhow!("Predicate did not evaluate to a boolean")),
}
}
#[cfg(test)]
mod tests {
use baml_types::BamlValue;
use super::*;
#[test]
fn test_render_expressions() {
let ctx = vec![
(
"a".to_string(),
BamlValue::List(vec![
BamlValue::Int(1),
BamlValue::Int(2),
BamlValue::Int(3),View on GitHub (pinned to bd85ce9dee)