{"record":{"id":"2d8ef6db455c2f02","repo":"BoundaryML/baml","slug":"unsupported-types-for-operator-at-2d8ef6","errorCode":null,"errorMessage":"unsupported types for <= operator at {:?}","messagePattern":"unsupported types for <= operator at (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-compiler/src/thir/interpret.rs","lineNumber":2455,"sourceCode":"            let equal = values_equal(&left_val.clone(), &right_val.clone());\n            BamlValueWithMeta::Bool(equal, meta.clone())\n        }\n        BinaryOperator::Neq => {\n            let not_equal = !values_equal(&left_val.clone(), &right_val.clone());\n            BamlValueWithMeta::Bool(not_equal, meta.clone())\n        }\n        BinaryOperator::Lt => {\n            let ord_opt = compare_values(&left_val.clone(), &right_val.clone())?;\n            let less = ord_opt\n                .map(|ord| matches!(ord, std::cmp::Ordering::Less))\n                .ok_or_else(|| anyhow!(\"unsupported types for < operator at {:?}\", meta.0))?;\n            BamlValueWithMeta::Bool(less, meta.clone())\n        }\n        BinaryOperator::LtEq => {\n            let ord_opt = compare_values(&left_val.clone(), &right_val.clone())?;\n            let less_eq = ord_opt\n                .map(|ord| matches!(ord, std::cmp::Ordering::Less | std::cmp::Ordering::Equal))\n                .ok_or_else(|| anyhow!(\"unsupported types for <= operator at {:?}\", meta.0))?;\n            BamlValueWithMeta::Bool(less_eq, meta.clone())\n        }\n        BinaryOperator::Gt => {\n            let ord_opt = compare_values(&left_val.clone(), &right_val.clone())?;\n            let greater = ord_opt\n                .map(|ord| matches!(ord, std::cmp::Ordering::Greater))\n                .ok_or_else(|| anyhow!(\"unsupported types for > operator at {:?}\", meta.0))?;\n            BamlValueWithMeta::Bool(greater, meta.clone())\n        }\n        BinaryOperator::GtEq => {\n            let ord_opt = compare_values(&left_val.clone(), &right_val.clone())?;\n            let greater_eq = ord_opt\n                .map(|ord| matches!(ord, std::cmp::Ordering::Greater | std::cmp::Ordering::Equal))\n                .ok_or_else(|| anyhow!(\"unsupported types for >= operator at {:?}\", meta.0))?;\n            BamlValueWithMeta::Bool(greater_eq, meta.clone())\n        }\n\n        // Logical operations","sourceCodeStart":2437,"sourceCodeEnd":2473,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-compiler/src/thir/interpret.rs#L2437-L2473","documentation":"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.","triggerScenarios":"Evaluating `a <= b` with incompatible operands: number vs string, string vs number, bools, arrays, maps, class instances, or null comparisons.","commonSituations":"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.","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 `<=`"],"exampleFix":"// before (.baml)\nif score <= max_score_str { ... } // max_score_str: string\n// after (.baml)\nif score <= max_score_str as float { ... }","handlingStrategy":"validation","validationCode":"// .baml — cast the bound before comparing\nlet max = max_score_str as float;\nif score <= max { ... }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["baml","interpreter","comparison","type-error"],"backgroundTag":"type-mismatch","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}