BoundaryML/baml · error
right operand of && must be bool at
Error message
right operand of && must be bool at {:?} What it means
The BAML compiler's interpreter short-circuits `&&`: when the left operand evaluates to `true`, the right operand must be a Bool for the result to be well-typed. This bail fires in evaluate_binary_op when the right operand of `&&` is any non-bool BamlValue (string, int, null, map, etc.). BAML's logical operators are strictly bool-typed and do not coerce truthy values.
Solutions
- Make the right operand explicitly boolean, e.g. wrap it in a comparison: `flag && (x != null)`.
- Check the right operand's declared type in the BAML schema; if it can be non-bool, restructure the expression with an if/else instead of `&&`.
- If a value may be null, use an explicit null check before the `&&` rather than relying on truthiness.
Example fix
// before (BAML) let ok = hasData && items; // after let ok = hasData && (items != null);
Defensive patterns
Strategy: type-guard
Validate before calling
// before relying on &&, ensure both sides are bool
function isBool(v) { return typeof v === 'boolean'; }
if (!isBool(rightOperand)) throw new Error('right operand of && must be bool'); Type guard
const isBool = (v) => typeof v === 'boolean';
Try / catch
try {
result = evaluate(expr);
} catch (e) {
if (String(e).includes('right operand of && must be bool')) {
// fix operand: coerce with explicit comparison
result = evaluate(fixBooleanOperands(expr));
} else throw e;
} Prevention
- Never rely on truthiness in BAML; always write explicit comparisons
- Keep a unit test per logical operator covering non-bool operands
- Type-check expressions at compile time before interpretation
When it happens
Trigger: Evaluating a BAML expression like `a && b` where `a` is true and `b` is a non-boolean value (e.g. `true && 1`, `cond && "yes"`, `flag && maybeNull`). The error surfaces at interpretation time with the source span in meta.0.
Common situations: Porting JavaScript/Python-style truthy short-circuit idioms into BAML; using `x ?? default`-style fallbacks written as `flag && fallback`; a variable whose type was widened to nullable or string but still used in a boolean context.
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
- left operand of && must be bool at
- left operand of || must be bool at
- right operand of || must be bool at
- array assignment on non-list value at
- bitwise ^= requires integer operands
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/eff70f11b6a7286b.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-compiler/src/thir/interpret.rs:2478
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),
},
BinaryOperator::Or => match left_val.clone() {
BamlValueWithMeta::Bool(true, _) => BamlValueWithMeta::Bool(true, meta.clone()),
BamlValueWithMeta::Bool(false, _) => 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),
},
// Bitwise operations (integer only)
BinaryOperator::BitAnd => match (left_val.clone(), right_val.clone()) {
(BamlValueWithMeta::Int(a, _), BamlValueWithMeta::Int(b, _)) => {
BamlValueWithMeta::Int(a & b, meta.clone())
}
_ => bail!("bitwise & requires integer operands at {:?}", meta.0),View on GitHub (pinned to bd85ce9dee)