BoundaryML/baml · error

Invalid left hand of assignment, only variables, instance…

Error message

Invalid left hand of assignment, only variables, instance fields and array elements can be assigned

What it means

A panic emitted when the left-hand side of an assignment statement is not one of the supported assignable forms: a local variable, an instance field access, or an indexed element. The BAML compiler does not support other assignment targets.

Solutions

  1. Rewrite the statement so the left side is a variable, obj.field, or collection[index]
  2. Assign the expression result to a variable first, then use it
  3. Check for a typo of `=` vs `==`

Example fix

// before
foo() = 5
// after
let result = foo()
// use result; assignment targets must be variables, fields, or elements
Defensive patterns

Strategy: validation

Validate before calling

// Validate assignment target before compiling:
// valid if Var(name) | FieldAccess{..} | Index{..}
fn is_valid_assign_target(expr: &Expr) -> bool {
    matches!(expr, Expr::Var(_) | Expr::FieldAccess { .. } | Expr::Index { .. })
}

Type guard

fn is_assignable_target(e: &Expr) -> bool {
    matches!(e, Expr::Var(_) | Expr::FieldAccess { .. } | Expr::Index { .. })
}

Prevention

When it happens

Trigger: Assignment to expressions like function calls `f() = x`, literals, parenthesized complex expressions, or other unsupported LHS forms in BAML source.

Common situations: Ported code from other languages assuming richer assignment targets; accidentally writing `=` where `==` was intended in a condition.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at engine/baml-compiler/src/codegen.rs:625

                        // Generate bytecode: load base, load value, store field
                        self.compile_expression(base);
                        self.compile_expression_with_block_behavior(value, true);
                        self.emit(Instruction::StoreField(field_index));
                    }
                    thir::Expr::ArrayAccess {base, index, meta: _} => {

                        self.compile_expression(base);
                        self.compile_expression(index);
                        self.compile_expression_with_block_behavior(value, true);

                        self.emit(match base.meta().1.as_ref().expect("must have a resolved type") {
                            TypeIR::List(_, _) => Instruction::StoreArrayElement,
                            TypeIR::Map(_, _, _) => Instruction::StoreMapElement,
                            _ => panic!("array access should be either map or array.")
                        });

                    }
                    _ => panic!("Invalid left hand of assignment, only variables, instance fields and array elements can be assigned"),
                }
            }
            thir::Statement::AssignOp {
                left,
                value,
                assign_op,
                ..
            } => {
                let binop = match assign_op {
                    hir::AssignOp::AddAssign => Instruction::BinOp(BinOp::Add),
                    hir::AssignOp::SubAssign => Instruction::BinOp(BinOp::Sub),
                    hir::AssignOp::MulAssign => Instruction::BinOp(BinOp::Mul),
                    hir::AssignOp::DivAssign => Instruction::BinOp(BinOp::Div),
                    hir::AssignOp::ModAssign => Instruction::BinOp(BinOp::Mod),
                    hir::AssignOp::BitAndAssign => Instruction::BinOp(BinOp::BitAnd),
                    hir::AssignOp::BitOrAssign => Instruction::BinOp(BinOp::BitOr),
                    hir::AssignOp::BitXorAssign => Instruction::BinOp(BinOp::BitXor),
                    hir::AssignOp::ShlAssign => Instruction::BinOp(BinOp::Shl),

View on GitHub (pinned to bd85ce9dee)