{"record":{"id":"91167b4f892fbbf5","repo":"BoundaryML/baml","slug":"operator-requires-boolean-operand-at","errorCode":null,"errorMessage":"! operator requires boolean operand at {:?}","messagePattern":"! operator requires boolean operand at (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-compiler/src/thir/interpret.rs","lineNumber":2546,"sourceCode":"        BinaryOperator::InstanceOf => match (left_val.clone(), right_val.clone()) {\n            (BamlValueWithMeta::Class(class, ..), BamlValueWithMeta::Class(right_class, ..)) => {\n                BamlValueWithMeta::Bool(class == right_class, meta.clone())\n            }\n            _ => bail!(\"instanceof requires class operands at {:?}\", meta.0),\n        },\n    })\n}\n\nfn evaluate_unary_op(\n    operator: &crate::hir::UnaryOperator,\n    val: &BamlValueWithMeta<ExprMetadata>,\n    meta: &ExprMetadata,\n) -> Result<BamlValueWithMeta<ExprMetadata>> {\n    use crate::hir::UnaryOperator;\n    Ok(match operator {\n        UnaryOperator::Not => match val.clone() {\n            BamlValueWithMeta::Bool(b, _) => BamlValueWithMeta::Bool(!b, meta.clone()),\n            _ => bail!(\"! operator requires boolean operand at {:?}\", meta.0),\n        },\n        UnaryOperator::Neg => match val.clone() {\n            BamlValueWithMeta::Int(i, _) => BamlValueWithMeta::Int(-i, meta.clone()),\n            BamlValueWithMeta::Float(f, _) => BamlValueWithMeta::Float(-f, meta.clone()),\n            _ => bail!(\"- operator requires numeric operand at {:?}\", meta.0),\n        },\n    })\n}\n\nfn values_equal(\n    left: &BamlValueWithMeta<ExprMetadata>,\n    right: &BamlValueWithMeta<ExprMetadata>,\n) -> bool {\n    match (left, right) {\n        (BamlValueWithMeta::Int(a, _), BamlValueWithMeta::Int(b, _)) => a == b,\n        (BamlValueWithMeta::Float(a, _), BamlValueWithMeta::Float(b, _)) => a == b,\n        (BamlValueWithMeta::Int(a, _), BamlValueWithMeta::Float(b, _)) => *a as f64 == *b,\n        (BamlValueWithMeta::Float(a, _), BamlValueWithMeta::Int(b, _)) => *a == *b as f64,","sourceCodeStart":2528,"sourceCodeEnd":2564,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-compiler/src/thir/interpret.rs#L2528-L2564","documentation":"Thrown when the unary `!` (logical not) operator is applied to a value that is not a Bool at runtime. The interpreter only implements Not for BamlValueWithMeta::Bool; all other variants bail. BAML does not implicitly truthiness-coerce values like JavaScript does.","triggerScenarios":"Evaluating `!x` where `x` is an int, float, string, null, list, or class instance instead of a bool. Common with values flowing from JSON parsing, optional fields, or function returns typed loosely.","commonSituations":"Negating a comparison result that was accidentally omitted (`!x` instead of `!(x == y)`), negating an optional/int flag from config, or applying ! to a string in a prompt-expression.","solutions":["Ensure the operand of ! is a boolean expression; add an explicit comparison, e.g. `!(x == 0)` instead of `!x`","Annotate the variable as bool so the typechecker catches non-bool values before interpretation","Convert truthiness manually, e.g. `x == null` or `x == \"\"` rather than `!x`","If the value is optional, unwrap/coalesce it to a bool first (`x ?? false`)"],"exampleFix":"// before (BAML)\nlet disabled = !retries;   // retries: int\n// after\nlet disabled = !(retries > 0);","handlingStrategy":"type-guard","validationCode":"// ensure the operand is boolean before negation\nif (typeof flag !== 'boolean') {\n  throw new Error(`! requires bool, got ${typeof flag}`);\n}","typeGuard":"const isBool = (v: unknown): v is boolean => typeof v === 'boolean';","tryCatchPattern":"try {\n  result = evaluate(expr);\n} catch (e) {\n  if (String(e).includes('! operator requires boolean operand')) {\n    // rewrite as explicit comparison\n  }\n  throw e;\n}","preventionTips":["Never rely on truthiness; write explicit comparisons","Annotate flags as bool in BAML schemas","Coalesce optionals before negation (x ?? false)"],"tags":["baml","interpreter","unary-operator","boolean"],"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"}