BoundaryML/baml · error

unsupported types for > operator at

Error message

unsupported types for > operator at {:?}

What it means

The `>` operator uses compare_values, which returns None for operand pairs with no defined ordering (different types or unordered types). evaluate_binary_op converts None into this bail, reporting the source span of the expression. Only mutually comparable, orderable values (numbers with numbers, strings with strings) are valid.

Solutions

  1. Cast both sides to a common numeric type (`as int` / `as float`) or compare strings with strings
  2. Print both operands before the check to identify the type mismatch
  3. Correct the field type in the schema/prompt so LLM output is numeric when needed
  4. Handle null/optional values explicitly before `>`

Example fix

// before (.baml)
if count > limit_str { ... } // limit_str: string
// after (.baml)
if count > limit_str as int { ... }
Defensive patterns

Strategy: validation

Validate before calling

// .baml — unify types before `>`
let lim = limit_str as int;
if count > lim { ... }

Prevention

When it happens

Trigger: Evaluating `a > b` where the operands are of different types (e.g. `"10" > 5`) or of non-orderable types (bool, array, map, class instance, null).

Common situations: Comparing LLM-returned strings against numeric literals; comparing values pulled from untyped containers; a numeric variable accidentally holding a string due to a schema type of string; comparing booleans with `>`.

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


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/85d20c80cb689196. Report an issue: GitHub.

Appendix: source

Thrown at engine/baml-compiler/src/thir/interpret.rs:2462

        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 operations
        BinaryOperator::And => match left_val.clone() {
            BamlValueWithMeta::Bool(false, _) => BamlValueWithMeta::Bool(false, meta.clone()),
            BamlValueWithMeta::Bool(true, _) => match right_val.clone() {
                BamlValueWithMeta::Bool(b, _) => BamlValueWithMeta::Bool(b, meta.clone()),
                _ => bail!("right operand of && must be bool at {:?}", meta.0),
            },
            _ => bail!("left operand of && must be bool at {:?}", meta.0),

View on GitHub (pinned to bd85ce9dee)