BoundaryML/baml · error

instanceof requires class operands at

Error message

instanceof requires class operands at {:?}

What it means

Thrown when BAML's `instanceof` binary operator is evaluated with operands that are not both Class values. instanceof is only defined for checking whether a value's class matches another class; primitives, lists, maps, media, etc. are unsupported and hit the bail. The interpreter deliberately restricts instanceof to class identity comparison.

Solutions

  1. Ensure both sides of instanceof are class values; use equality (==) for primitives/enums instead
  2. Check the actual runtime type of the left operand before applying instanceof
  3. If checking a subtype relationship, verify the class is instantiated (Class value) rather than holding a raw payload
  4. Refactor to use a discriminating field or enum match instead of instanceof for non-class types

Example fix

// before (BAML)
if (result instanceof MyResult) { ... }  // result is a string
// after
if (result == "expected") { ... }  // or ensure result is constructed as a MyResult class instance
Defensive patterns

Strategy: type-guard

Validate before calling

// ensure both operands are class instances before instanceof
if (typeof x !== 'object' || x === null || typeof Y !== 'function') {
  throw new Error('instanceof needs class operands');
}

Type guard

const isClassValue = (v: unknown): boolean => v !== null && typeof v === 'object' && v.__kind === 'class';

Try / catch

try {
  result = evaluate(expr);
} catch (e) {
  if (String(e).includes('instanceof requires class operands')) {
    // switch to equality check or fix operand construction
  }
  throw e;
}

Prevention

When it happens

Trigger: Writing `x instanceof Y` in BAML where `x` evaluates to a non-class value (int, string, list, enum, media) or where the right-hand side is not a class reference. Also fires when a value expected to be a class instance is actually a primitive (e.g. deserialized from JSON).

Common situations: Using instanceof for type checks on primitives or enums (which are not classes in BAML), testing values returned from function calls whose static type was unknown, or mistaking a class name for an instance on either side.

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/a587c600ae3333da. Report an issue: GitHub.

Appendix: source

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

                }
                BamlValueWithMeta::Int(a << b, meta.clone())
            }
            _ => bail!("shift << requires integer operands at {:?}", meta.0),
        },
        BinaryOperator::Shr => match (left_val.clone(), right_val.clone()) {
            (BamlValueWithMeta::Int(a, _), BamlValueWithMeta::Int(b, _)) => {
                if b < 0 {
                    bail!("negative shift amount at {:?}", meta.0);
                }
                BamlValueWithMeta::Int(a >> b, meta.clone())
            }
            _ => bail!("shift >> requires integer operands at {:?}", meta.0),
        },
        BinaryOperator::InstanceOf => match (left_val.clone(), right_val.clone()) {
            (BamlValueWithMeta::Class(class, ..), BamlValueWithMeta::Class(right_class, ..)) => {
                BamlValueWithMeta::Bool(class == right_class, meta.clone())
            }
            _ => bail!("instanceof requires class operands at {:?}", meta.0),
        },
    })
}

fn evaluate_unary_op(
    operator: &crate::hir::UnaryOperator,
    val: &BamlValueWithMeta<ExprMetadata>,
    meta: &ExprMetadata,
) -> Result<BamlValueWithMeta<ExprMetadata>> {
    use crate::hir::UnaryOperator;
    Ok(match operator {
        UnaryOperator::Not => match val.clone() {
            BamlValueWithMeta::Bool(b, _) => BamlValueWithMeta::Bool(!b, meta.clone()),
            _ => bail!("! operator requires boolean operand at {:?}", meta.0),
        },
        UnaryOperator::Neg => match val.clone() {
            BamlValueWithMeta::Int(i, _) => BamlValueWithMeta::Int(-i, meta.clone()),
            BamlValueWithMeta::Float(f, _) => BamlValueWithMeta::Float(-f, meta.clone()),

View on GitHub (pinned to bd85ce9dee)