BoundaryML/baml · error

push() can only be called on arrays at

Error message

push() can only be called on arrays at {:?}

What it means

`push()` is only valid on array (List) values. When the receiver variable holds any other type — string, int, map/class, null — the interpreter's match on the cell contents falls through to this bail arm.

Solutions

  1. Ensure the receiver is initialized as an array before pushing: `let arr = [];`
  2. Check the variable's actual runtime type/value before calling push
  3. If pushing key/value data, use a map/class with appropriate operations instead
  4. Trace where the variable is assigned; a null from an upstream call is a common root cause

Example fix

// before
let arr;        // ends up null
arr.push(x)
// after
let arr = [];
arr.push(x);
Defensive patterns

Strategy: type-guard

Validate before calling

// verify the receiver holds an array before push
if (!Array.isArray(receiver) || receiver == null) { throw new Error('push receiver must be an array'); }

Type guard

function isBamlList(v) { return v != null && v.__baml_type === 'List'; }

Try / catch

try { arr.push(x); } catch (e) { if (String(e).includes('push() can only be called on arrays')) { /* initialize as array or fix upstream type */ } else { throw e; } }

Prevention

When it happens

Trigger: Calling `push` on a variable whose runtime value is not a List: a class instance, a string, a number, or null (e.g. an uninitialized or wrongly-typed variable).

Common situations: A variable declared or inferred as something other than an array (often null from a failed parse or an LLM response) then used with push; confusing maps/objects with arrays when porting JS habits.

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

Appendix: source

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

                                watch_handler,
                                function_name,
                            )
                            .await?,
                        )?);
                    }

                    // Mutate the array
                    let mut receiver_val = receiver_cell.lock().unwrap();
                    match &mut *receiver_val {
                        BamlValueWithMeta::List(items, _) => {
                            if arg_vals.len() != 1 {
                                bail!("push() expects exactly one argument at {:?}", meta.0);
                            }
                            items.push(arg_vals[0].clone());
                            // Return void/unit
                            EvalValue::Value(BamlValueWithMeta::Null(meta.clone()))
                        }
                        _ => bail!("push() can only be called on arrays at {:?}", meta.0),
                    }
                } else {
                    // Non-mutating methods
                    let receiver_val = expect_value(
                        evaluate_expr(
                            receiver,
                            scopes,
                            thir,
                            run_llm_function,
                            watch_handler,
                            function_name,
                        )
                        .await?,
                    )?;

                    // Evaluate arguments
                    let mut arg_vals: Vec<BamlValueWithMeta<ExprMetadata>> =
                        Vec::with_capacity(args.len());

View on GitHub (pinned to bd85ce9dee)