BoundaryML/baml · error

array access should be either map or array.

Error message

array access should be either map or array.

What it means

A panic during codegen of an element-assignment statement: the compiler matched the resolved type of the indexed base expression expecting List or Map, and hit anything else (e.g. a primitive, string, or class type). The type resolution metadata lacked a List/Map type where indexed assignment was used.

Source

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

                        let Some(&field_index) = resolved_fields.get(field) else {
                            panic!("undefined field: {class_name}.{field}");
                        };

                        // 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),

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Ensure the indexed variable is declared/typed as a list or map in BAML
  2. Fix the variable's type annotation or initializer
  3. If the resolved type is legitimately missing, report a compiler bug to the BAML maintainers

Example fix

// before
let name = "hello"
name[0] = 'H'
// after
let chars = ["h", "e", "l", "l", "o"]
chars[0] = "H"
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_indexable(t: &TypeIR) -> Result<(), String> {
    match t {
        TypeIR::List(_, _) | TypeIR::Map(_, _, _) => Ok(()),
        other => Err(format!("cannot index-assign into type {:?}", other)),
    }
}

Type guard

fn is_indexable(t: Option<&TypeIR>) -> bool {
    matches!(t, Some(TypeIR::List(_, _)) | Some(TypeIR::Map(_, _, _)))
}

Prevention

When it happens

Trigger: `arr[i] = v` where `arr`'s resolved type is neither List nor Map; unresolved type metadata; assigning into a string or scalar via index syntax.

Common situations: Index-assigning into a non-collection variable after a type change; code where type inference marked the variable as a different kind; strings mistakenly treated as indexable.

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