BoundaryML/baml · error

undefined function: {name}

Error message

undefined function: {name}

What it means

A panic during codegen of a DeclareAndAssign with a watch clause: when the watch trigger is WatchWhen::FunctionName, the named function must exist in the compiler's globals map. The panic reports the variable name (not the function name), so the message text can be misleading — the actual lookup that failed is the watch function name.

Source

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

                        self.emit(store_instr);
                    }
                    _ => panic!("Invalid left hand of assignment, only variables, instance fields and array elements can be assigned"),
                }
            }
            thir::Statement::DeclareAndAssign {
                name, value, watch, ..
            } => {
                self.compile_expression_with_block_behavior(value, true);
                let local_index = self.track_local(name);
                if let Some(spec) = watch {
                    self.emit_string_literal(&spec.name); // This adds LoadConst

                    match &spec.when {
                        WatchWhen::FunctionName(fn_name) => {
                            if let Some(&index) = self.globals.get(fn_name.name()) {
                                self.emit(Instruction::LoadGlobal(index));
                            } else {
                                panic!("undefined function: {name}");
                            }
                        }
                        WatchWhen::Never => {}

                        WatchWhen::Manual => {
                            self.emit_string_literal("manual");
                        }

                        WatchWhen::Auto => {
                            let index = self.add_constant(Value::Null);
                            self.emit(Instruction::LoadConst(index));
                        }
                    }

                    self.emit(Instruction::Watch(local_index));
                }
            }
            thir::Statement::Return { expr, .. } => {

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Fix the function name in the watch clause to match a defined function
  2. Define the referenced function before/where it is watched
  3. Remove the watch clause if the trigger function is no longer needed

Example fix

// before
let v = expr watch MyFuntion
// after
let v = expr watch MyFunction
Defensive patterns

Strategy: validation

Validate before calling

fn validate_watch_fn(globals: &[&str], fn_name: &str) -> Result<(), String> {
    if !globals.contains(&fn_name) {
        return Err(format!("watch function '{}' is not defined", fn_name));
    }
    Ok(())
}

Prevention

When it happens

Trigger: `watch` attribute referencing a function name that is not a registered global function; misspelled function in a watch clause.

Common situations: Renaming or deleting a watched function without updating watch clauses; typos in the watch target function name.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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