BoundaryML/baml · error
unsupported types for <= operator at
Error message
unsupported types for <= operator at {:?} What it means
The `<=` operator relies on compare_values; when the operand pair has no defined ordering (mismatched types, or non-orderable types like bool/array/map/class), it returns None and this bail fires with the source span. Both operands must be of a mutually comparable, orderable type.
Solutions
- Normalize both operands to one type before comparing (`as int`, `as float`, or both as strings)
- Log/print both operands and their types at the comparison site
- Fix the producer of the wrongly-typed value (schema field type or cast)
- Guard against null/missing values before `<=`
Example fix
// before (.baml)
if score <= max_score_str { ... } // max_score_str: string
// after (.baml)
if score <= max_score_str as float { ... } Defensive patterns
Strategy: validation
Validate before calling
// .baml — cast the bound before comparing
let max = max_score_str as float;
if score <= max { ... } Prevention
- Normalize threshold/bound values to the same type as the compared value
- Keep config-driven bounds typed consistently (prefer numeric config fields)
- Add casts after any string parsing used in comparisons
- Test comparisons with values sourced from LLM output to catch type drift
When it happens
Trigger: Evaluating `a <= b` with incompatible operands: number vs string, string vs number, bools, arrays, maps, class instances, or null comparisons.
Common situations: Threshold checks where one side came from a string-parsed config or LLM output; comparing a numeric field to a value stored as string in a map; version comparisons done on strings mixed with numbers.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- unsupported types for >= operator at
- unsupported types for > operator at
- unsupported types for < operator at
- modulo by zero at
- unsupported types for % operator at
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/2d8ef6db455c2f02.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-compiler/src/thir/interpret.rs:2455
let equal = values_equal(&left_val.clone(), &right_val.clone());
BamlValueWithMeta::Bool(equal, meta.clone())
}
BinaryOperator::Neq => {
let not_equal = !values_equal(&left_val.clone(), &right_val.clone());
BamlValueWithMeta::Bool(not_equal, meta.clone())
}
BinaryOperator::Lt => {
let ord_opt = compare_values(&left_val.clone(), &right_val.clone())?;
let less = ord_opt
.map(|ord| matches!(ord, std::cmp::Ordering::Less))
.ok_or_else(|| anyhow!("unsupported types for < operator at {:?}", meta.0))?;
BamlValueWithMeta::Bool(less, meta.clone())
}
BinaryOperator::LtEq => {
let ord_opt = compare_values(&left_val.clone(), &right_val.clone())?;
let less_eq = ord_opt
.map(|ord| matches!(ord, std::cmp::Ordering::Less | std::cmp::Ordering::Equal))
.ok_or_else(|| anyhow!("unsupported types for <= operator at {:?}", meta.0))?;
BamlValueWithMeta::Bool(less_eq, meta.clone())
}
BinaryOperator::Gt => {
let ord_opt = compare_values(&left_val.clone(), &right_val.clone())?;
let greater = ord_opt
.map(|ord| matches!(ord, std::cmp::Ordering::Greater))
.ok_or_else(|| anyhow!("unsupported types for > operator at {:?}", meta.0))?;
BamlValueWithMeta::Bool(greater, meta.clone())
}
BinaryOperator::GtEq => {
let ord_opt = compare_values(&left_val.clone(), &right_val.clone())?;
let greater_eq = ord_opt
.map(|ord| matches!(ord, std::cmp::Ordering::Greater | std::cmp::Ordering::Equal))
.ok_or_else(|| anyhow!("unsupported types for >= operator at {:?}", meta.0))?;
BamlValueWithMeta::Bool(greater_eq, meta.clone())
}
// Logical operationsView on GitHub (pinned to bd85ce9dee)