BoundaryML/baml · error
assign to undeclared variable
Error message
assign to undeclared variable `{}` What it means
The BAML interpreter's `assign` helper walks the active scopes and, when no scope contains a cell for the variable name, bails with `assign to undeclared variable \`{name}\``. BAML requires variables to be declared (e.g. via `let` / parameter bindings) before they can be reassigned, so assignment to a never-declared name is a hard runtime error in the interpreted THIR evaluator.
Solutions
- Declare the variable before assigning to it (e.g. `let x = ...`) so a scope cell exists
- Check the variable name for typos against the declaration
- If the value should be produced by an expression, bind it with `let` instead of assigning
- Ensure the assignment is not executed in a scope where the declaration is not visible (e.g. inside a different function/block)
Example fix
// before (BAML) let count = 0; count = count + 1; // ok totla = count; // assign to undeclared variable `totla` // after let count = 0; count = count + 1; let total = count;
Defensive patterns
Strategy: validation
Validate before calling
// BAML: ensure the target is declared before assigning let message = ""; // declaration creates the scope cell message = "hello"; // now safe
Prevention
- Declare every variable with let/params before assigning
- Enable editor rename-refactor instead of retyping variable names
- Keep scopes shallow so declarations stay visible where assigned
When it happens
Trigger: Executing a `x = value` assignment (via `assign_to_expr` on a plain `Expr::Var` target) where `x` was never introduced by a declaration, function parameter, or for-loop binding in any active scope.
Common situations: Typo in a variable name on the left side of an assignment (e.g. `mesage = ...` after `let message = ...`); attempting to create a variable by plain assignment in a BAML expression block as if it were Python/JS; using a variable defined in an inner scope after it closed.
Related errors
- array assignment index out of bounds
- array assignment on non-list value at
- array assignment requires a non-negative integer index at
- Complex assignment targets not yet supported
- field assignment on non-map/class
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/638f915c62752e38.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-compiler/src/thir/interpret.rs:1447
fn declare_with_cell(
scopes: &mut [Scope],
name: &str,
cell: Arc<Mutex<BamlValueWithMeta<ExprMetadata>>>,
) {
if let Some(scope) = scopes.last_mut() {
scope.variables.insert(name.to_string(), cell);
}
}
fn assign(scopes: &mut [Scope], name: &str, value: BamlValueWithMeta<ExprMetadata>) -> Result<()> {
for s in scopes.iter_mut().rev() {
if let Some(cell) = s.variables.get_mut(name) {
*cell.lock().unwrap() = value;
return Ok(());
}
}
bail!("assign to undeclared variable `{}`", name)
}
async fn assign_to_expr<F, Fut>(
target: &Expr<ExprMetadata>,
new_value: BamlValueWithMeta<ExprMetadata>,
scopes: &mut Vec<Scope>,
thir: &THir<ExprMetadata>,
run_llm_function: &mut F,
watch_handler: &SharedWatchHandler,
function_name: &str,
) -> Result<()>
where
F: LlmHandler<Fut>,
Fut: LlmFuture,
{
let mut current_expr = target;
let mut value_to_assign = new_value;
View on GitHub (pinned to bd85ce9dee)