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
- Check the function name used in the `watch` options and correct any typo so it matches a defined function
- Ensure the referenced function is defined in the same compilation unit and registered before the watch statement is compiled
- Update stale references after renaming the function
- 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
- Grep for `watch` option callbacks and diff them against your defined function names before compiling
- Rename functions via tooling (LSP rename) so watch references update automatically
- Keep watch callbacks in the same file/unit that registers globals
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
- undefined function: {name}
- watch codegen error: undefined variable: {variable}
- Field access on non-class type
- undefined class: {class_name}
- undefined field: {class_name}.{field}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/0e3965fafd9f22c4.
Report an issue: GitHub.