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

  1. Inspect the inner debug payload after 'Error evaluating constraint:' for the root cause.
  2. Make sure the predicate references only fields that exist on the value being checked.
  3. Ensure the predicate expression evaluates strictly to true/false (e.g. {{ this.len > 5 }}, not {{ this.len }}).
  4. 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

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


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)