BoundaryML/baml · error

method name must be an identifier at

Error message

method name must be an identifier at {:?}

What it means

Method-call expressions (`receiver.method(args)`) in the BAML interpreter require the method portion to be a plain identifier. If the parser produced anything else in the method position (e.g. a nested expression, an indexed access, a call result), evaluation bails with this error.

Solutions

  1. Use a literal method name identifier at the call site: `obj.push(item)`
  2. Bind the result to a variable and call a known method on it instead of dynamic dispatch
  3. Check parentheses/bracket placement so the compiler parses the method as a Var expression

Example fix

// before
arr["push"](item)
// after
arr.push(item)
Defensive patterns

Strategy: validation

Validate before calling

// ensure the call shape is receiver.literalMethod(args)
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(methodName)) { throw new Error('method name must be an identifier'); }

Type guard

function isMethodIdentifier(e) { return e != null && e.kind === 'Var' && typeof e.name === 'string'; }

Try / catch

try { evalCall(); } catch (e) { if (String(e).includes('method name must be an identifier')) { /* rewrite call with literal method name */ } else { throw e; } }

Prevention

When it happens

Trigger: Calling a method via a non-identifier expression, such as `obj["push"](x)`, `(getFn())(arg)`, or chained access where the method name is computed dynamically.

Common situations: Dynamic method dispatch attempted in BAML code (methods chosen from a variable or map lookup); mis-parenthesized chained calls; code generated by a template that interpolated a method expression.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

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

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

                let result = evaluate_unary_op(operator, &val, meta)?;
                EvalValue::Value(result)
            }
            Expr::MethodCall {
                receiver,
                method,
                args,
                meta,
            } => {
                // Extract method name
                let method_name = match method.as_ref() {
                    Expr::Var(name, _) => name.clone(),
                    _ => bail!("method name must be an identifier at {:?}", meta.0),
                };

                // For mutating methods like push(), we need the cell reference
                if method_name == "push" {
                    // Get the receiver as a reference (cell) if possible
                    let receiver_eval = evaluate_expr(
                        receiver,
                        scopes,
                        thir,
                        run_llm_function,
                        watch_handler,
                        function_name,
                    )
                    .await?;

                    let receiver_cell = match receiver_eval {
                        EvalValue::Reference(cell) => cell,
                        _ => bail!("push() can only be called on a variable at {:?}", meta.0),

View on GitHub (pinned to bd85ce9dee)