BoundaryML/baml · error

watch options codegen: undefined function: {fn_name}

Error message

watch options codegen: undefined function: {fn_name}

What it means

This is a compiler-internal panic raised during bytecode generation for a `watch` statement whose callback was specified by function name. Before emitting `LoadGlobal`, the codegen looks the function name up in the current global symbol table; if the name is absent, the THIR passed name-checking but codegen cannot resolve it, which is treated as an unrecoverable compiler invariant violation rather than a user-facing diagnostic.

Source

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

                match when.as_ref() {
                    Some(WatchWhen::Manual) => {
                        self.emit_string_literal("manual");
                    }

                    Some(WatchWhen::Never) => {
                        self.emit_string_literal("never");
                    }

                    Some(WatchWhen::Auto) => {
                        // No action needed.
                    }

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

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

                self.emit(Instruction::Watch(local_index));
            }
            thir::Statement::WatchNotify { variable, .. } => {
                let Some(local_index) = self.locals.get(variable).copied() else {
                    panic!("watch codegen error: undefined variable: {variable}");
                };

                self.emit(Instruction::Notify(local_index));
            }

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Check the function name used in the `watch` options and correct any typo so it matches a defined function
  2. Ensure the referenced function is defined in the same compilation unit and registered before the watch statement is compiled
  3. Update stale references after renaming the function
  4. If the name is legitimately defined, file a compiler bug: this indicates name resolution and codegen globals are out of sync

Example fix

// before
watch stream when myWtachFn(x)
// after
watch stream when myWatchFn(x)
Defensive patterns

Strategy: validation

Validate before calling

// Before compiling, verify every watch-callback name resolves
fn validate_watch_fns(src: &str, defined_fns: &HashSet<&str>) -> Result<(), String> {
    for name in extract_watch_fn_names(src) {
        if !defined_fns.contains(name.as_str()) {
            return Err(format!("watch callback `{name}` is not a defined function"));
        }
    }
    Ok(())
}

Prevention

When it happens

Trigger: Compiling a BAML function whose `watch ... when <fn_name>` option references a function name that is not present in `self.globals` — e.g. the watch callback names a function that was never defined, was renamed, or was not registered as a global during earlier compile phases.

Common situations: Typos in the watch callback function name; referencing a function defined in another file that was not imported/registered; refactoring a function name without updating `watch` options; compiler bugs where name resolution and globals registration disagree.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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