BoundaryML/baml · error · anyhow::Error
Error evaluating constraint
Error message
Error evaluating constraint: {:?} What it means
BAML evaluates @assert/@check constraint predicates against a value using Jinja expressions. When evaluate_predicate itself errors (e.g. the predicate did not render to a boolean), the error is wrapped as 'Error evaluating constraint: {:?}'. This surfaces during argument coercion when checking nested constraints.
Solutions
- Inspect the inner debug payload after 'Error evaluating constraint:' for the root cause.
- Make sure the predicate references only fields that exist on the value being checked.
- Ensure the predicate expression evaluates strictly to true/false (e.g. {{ this.len > 5 }}, not {{ this.len }}).
- Test the constraint expression standalone with a sample value.
Example fix
// before
@assert({{ this.items }})
// after
@assert({{ this.items|length > 0 }}) Defensive patterns
Strategy: validation
Validate before calling
// validate predicate fields before coercion
fn predicate_fields_exist(predicate: &str, value: &serde_json::Value) -> bool {
// ensure 'this.<field>' references exist on the value
predicate.split("this.").skip(1).all(|rest| {
let field: String = rest.chars().take_while(|c| c.is_alphanumeric() || *c == '_').collect();
field.is_empty() || value.get(&field).is_some()
})
} Try / catch
match evaluate_predicate(&value, &expr) {
Ok(true) => { /* pass */ }
Ok(false) => { /* constraint failed */ }
Err(e) => eprintln!("constraint eval error: {e:?}"), // includes field-level cause
} Prevention
- Reference only fields that exist on the checked value.
- Ensure predicates compare to produce true/false.
- Test each @assert expression against sample values.
When it happens
Trigger: coerce_arg -> first_failing_assert_nested encounters a constraint whose Jinja expression fails to evaluate: undefined 'this' fields referenced in the predicate, runtime errors in the expression, or a non-boolean result.
Common situations: An @assert predicate like {{ this.len > 5 }} applied to a value without field 'len'; predicate returning a string/number instead of a boolean; predicates written against the wrong field name after a schema refactor.
Related errors
- assertion failed
- baml.errors.InvalidArgument
- baml.fetch_as: expected header key to be a valid HTTP…
- Cannot generate HIR/bytecode due to validation errors
- Class does not have a field
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/9684c0fe355cc59b.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-lib/baml-core/src/ir/ir_helpers/to_baml_arg.rs:651
/// Search a potentially deeply-nested `BamlValue` for any failing asserts,
/// returning the first one encountered.
fn first_failing_assert_nested<'a>(
ir: &'a IntermediateRepr,
baml_value: &BamlValue,
field_type: &'a TypeIR,
) -> anyhow::Result<Option<Constraint>> {
let value_with_types = ir.distribute_type(baml_value.clone(), field_type.clone())?;
let first_failure = value_with_types
.iter()
.map(|value_node| {
let constraints = value_node.meta().meta().constraints.clone();
constraints
.into_iter()
.filter_map(|c| {
let constraint = c.clone();
let baml_value: BamlValue = value_node.into();
let result = evaluate_predicate(&baml_value, &c.expression).map_err(|e| {
anyhow::anyhow!(format!("Error evaluating constraint: {:?}", e))
});
match result {
Ok(false) => {
if c.level == ConstraintLevel::Assert {
Some(Ok(constraint))
} else {
None
}
}
Ok(true) => None,
Err(e) => Some(Err(e)),
}
})
.collect::<Vec<_>>()
})
.flat_map(|x| x.into_iter())
.next();
first_failure.transpose()View on GitHub (pinned to bd85ce9dee)