BoundaryML/baml · error · VmPanic
baml.panics.StackOverflow
baml.panics.StackOverflow
Error message
stack overflow
What it means
Raised when the VM's call/eval stack exceeds its maximum depth. This protects the interpreter from unbounded recursion exhausting host memory. It is a control-flow limit, not a memory allocation failure.
Source
Thrown at baml_language/crates/bex_vm_types/src/errors.rs:48
/// cold overflow path, so the `String` alloc never touches hot code.
#[error("integer overflow: {message}")]
IntegerOverflow { message: String },
// Raised by array and byte-array subscripting, so the message stays generic
// ("index", not "array index").
#[error("index out of bounds: {index} of {length}")]
IndexOutOfBounds { index: i64, length: usize },
#[error("invalid field access: field {field_index} of {field_count}")]
InvalidFieldAccess {
field_index: usize,
field_count: usize,
},
#[error("key not found in map")]
MapKeyNotFound,
#[error("stack overflow")]
StackOverflow,
#[error("assertion failed")]
AssertionFailed,
#[error("unreachable code executed")]
Unreachable,
#[error("operation cancelled")]
Cancelled,
/// A user-caused panic from `baml.sys.panic`, and the stdlib's panic of
/// record for a user-violated native invariant (e.g. a reflection kind
/// view's `_ty` field overwritten with a type of a different kind).
#[error("baml.sys.panic: {message}")]
UserPanic { message: String },
/// A clean process-termination request from `baml.sys.exit(code)`.View on GitHub (pinned to bd85ce9dee)
Solutions
- Fix the recursion: add or repair the base case so recursion terminates.
- Rewrite deep recursion iteratively with an explicit worklist/stack.
- Catch `baml.panics.StackOverflow` at a top-level boundary to fail gracefully, though recovery is limited.
Example fix
// before
fn walk(n) { return walk(n); } // no base case
// after
fn walk(n) { if (n <= 0) { return 0; } return walk(n - 1); } Defensive patterns
Strategy: validation
Validate before calling
// BAML: cap recursion depth up front
fn walk(n: int, depth: int) -> int {
if (depth > 10_000) { return err("too deep"); }
...
} Try / catch
// BAML
try {
return recurse(input);
} catch (e: baml.panics.StackOverflow) {
return err("input too deeply nested");
} Prevention
- Always verify recursive base cases are reachable
- Add a depth parameter to recursive traversals
- Convert deep recursion to iteration with an explicit stack
When it happens
Trigger: Deeply or infinitely recursive BAML functions, mutual recursion without a base case, or extremely deep non-recursive evaluation (e.g. deeply nested closures/chain calls) exceeding the VM stack limit.
Common situations: Recursive tree/graph traversal without memoization, recursion whose base case depends on data that never terminates, porting code written for a host language with a much larger stack.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- baml.panics.IntegerOverflow
- baml.panics.IndexOutOfBounds
- baml.panics.InvalidFieldAccess
- baml.panics.MapKeyNotFound
- baml.panics.AssertionFailed
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/46d5aad81acc15d4.
Report an issue: GitHub.