BoundaryML/baml · error · VmError
uncaught throw: {0:?}
Error message
uncaught throw: {0:?} What it means
VmError::Thrown wraps a VmThrown value representing a catchable throw (panic or error value) inside the BAML VM that was never caught. It is primarily an internal unwinding signal; when it surfaces to the user it means an exception raised in BAML code escaped without any matching catch handler.
Source
Thrown at baml_language/crates/bex_vm_types/src/errors.rs:434
value,
profiler_kind: ProfilerErrorKind::Rethrow,
language_is_rethrow,
origin: VmUnwindOrigin::unresolved(source),
}
}
#[must_use]
pub const fn with_origin(mut self, origin: VmUnwindOrigin) -> Self {
self.origin = origin;
self
}
}
/// Any kind of virtual machine error.
#[derive(Debug, Error, PartialEq, Clone)]
pub enum VmError {
/// Catchable (panics and error values) — internal signal for exception unwinding.
#[error("uncaught throw: {0:?}")]
Thrown(VmThrown),
/// An exception that escaped all catch handlers, with captured stack trace.
#[error("uncaught throw: {value:?}")]
ThrownUnhandled {
value: Value,
trace: Vec<StackFrame>,
},
/// Fatal VM errors
#[error("{0}")]
InternalError(#[from] VmInternalError),
/// Fatal VM error with captured stack trace.
/// Produced by `exec()` wrapper from `InternalError`.
#[error("{}", format_internal_error(source, trace))]
TracedInternalError {
source: VmInternalError,
trace: Vec<StackFrame>,
},
}View on GitHub (pinned to bd85ce9dee)
Solutions
- Wrap the failing BAML expression/call in a catch handler appropriate to the thrown value type.
- Inspect the debug-formatted VmThrown in the message to see exactly what was thrown and from where.
- Fix the root cause (the operation that threw) once identified from the thrown value.
- Add top-level error handling in the host when calling BAML functions so uncaught throws are reported cleanly.
Example fix
// before: no handler
let r = risky();
// after
let r = catch risky() {
case e => "fallback"
} Defensive patterns
Strategy: try-catch
Try / catch
match vm_result {
Err(BexError::Thrown(thrown)) => {
eprintln!("uncaught VM throw: {:?}", thrown);
}
other => other?,
} Prevention
- Add catch handlers around every fallible BAML call.
- Log the debug formatting of VmThrown to identify throw sources.
- Handle errors close to where they are raised rather than letting them escape.
- Add a top-level handler in the host when invoking BAML entry points.
When it happens
Trigger: BAML code executes a throw/panic and no enclosing catch block matches; native functions raise catchable errors that bubble to the top of the VM; a thrown Value (e.g. a user-defined class instance) is not intercepted by any handler.
Common situations: Omitting a catch handler for fallible BAML logic; a runtime or client error (e.g. LlmClient failure) being re-thrown as a VM throw; user-defined exception classes thrown in helpers and never caught at the call site.
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
- uncaught throw: {value:?}
- baml.panics.DivisionByZero
- baml.panics.IntegerOverflow
- baml.panics.IndexOutOfBounds
- baml.panics.InvalidFieldAccess
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/b6f4b4ac4c29b3cc.
Report an issue: GitHub.