BoundaryML/baml · error
Variable ' ' not found for $watch.notify()
Error message
Variable '{}' not found for $watch.notify() What it means
The BAML interpreter's $watch.notify() mechanism looks up the named variable in the current scope chain to fire a watch notification. If the variable is not found in any scope, the interpreter returns an error instead of notifying. This means the watch target referenced in the notify call no longer exists (or never existed) in the executing scope.
Solutions
- Correct the variable name passed to $watch.notify to match a variable in the current scope
- Move the notify call into the same block/scope where the variable is declared
- Declare the variable before the notify call executes
- Verify @watch registration happened for that variable (register_watch_variable) before notifying
Example fix
// before $watch.notify(watchedVale) // after $watch.notify(watchedValue)
Defensive patterns
Strategy: validation
Validate before calling
fn validate_watch_target(var: &str, scopes: &[Scope]) -> Result<(), String> {
if scopes.iter().rev().any(|s| s.contains(var)) { Ok(()) }
else { Err(format!("'{}' not in scope for $watch.notify", var)) }
} Type guard
fn is_in_scope(name: &str, scopes: &[Scope]) -> bool { scopes.iter().rev().any(|s| s.contains(name)) } Prevention
- Only call $watch.notify on variables declared in the same or an enclosing live scope
- Keep watch targets and notify calls in sync during renames
- Verify @watch registration exists for the variable before notifying
When it happens
Trigger: Executing $watch.notify(some_var) (or equivalent watch handling in handle_statement) where some_var is not registered in the active scopes — e.g. notifying inside a block where the variable was never declared, after it went out of scope, or with a misspelled name.
Common situations: Typo in the variable passed to $watch.notify; calling notify from a helper block where the watched variable is out of scope; renaming a watched variable without updating notify calls.
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
- Environment variable
- Filter function ' ' must return a boolean, got
- Filter function ' ' must take exactly 1 parameter (current…
- arity mismatch: expected
- array access on non-list at
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/4235944acf738665.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-compiler/src/thir/interpret.rs:158
.watch_variables
.iter()
.find(|wv| Arc::ptr_eq(&wv.value_ref, value_ref))
.map(|wv| wv.spec.name.clone())
.unwrap_or_else(|| var_name.to_string());
let current_value = value_ref.lock().unwrap();
let watch_value = expr_value_to_watch_value(current_value.clone());
let notification = crate::watch::WatchNotification::new_var(
var_name.to_string(), // variable name
channel_name, // current channel name from WatchSpec
watch_value,
function_name.to_string(),
);
watch_handler.lock().unwrap().notify(notification);
return Ok(());
}
}
bail!("Variable '{}' not found for $watch.notify()", var_name)
}
enum EvalValue {
Value(BamlValueWithMeta<ExprMetadata>),
Reference(Arc<Mutex<BamlValueWithMeta<ExprMetadata>>>),
Function(usize, Arc<Block<ExprMetadata>>, ExprMetadata),
}
#[derive(Debug)]
enum ControlFlow {
Normal(BamlValueWithMeta<ExprMetadata>),
Break,
Continue,
Return(BamlValueWithMeta<ExprMetadata>),
}
/// Check all @watch variables for changes and fire notifications
///View on GitHub (pinned to bd85ce9dee)