BoundaryML/baml · error · VmBamlError
host callable error: {message} [class={class_name}, lang={la
Error message
host callable error: {message} [class={class_name}, lang={language:?}] What it means
This is the HostCallable variant of the VM error enum: an error value that originated in the host language (Python, TypeScript, Ruby, etc.) when calling into a host callable from BAML. It carries class_name, message, optional traceback and language, plus a handle referencing the original host exception object in the process-global host-value table so the host runtime can rehydrate the real exception. Engine-side faults with no underlying host exception must NOT use this variant — those route through VmInternalError::BridgeFailure.
Source
Thrown at baml_language/crates/bex_vm_types/src/errors.rs:157
/// An error value from the host language that has no direct BAML
/// representation. The `handle` is the load-bearing field — it
/// references the original host exception object via the
/// process-global host-value table, so the originating runtime can
/// recover the exact native exception on round-trip. The
/// `class_name` / `message` / `language` / `traceback` fields are
/// purely metadata for debugging, logging, and user-facing
/// formatting — they do not participate in error matching or
/// rehydration.
///
/// Surfaces in BAML as a `baml.errors.HostCallable` Instance whose
/// `_handle` field is materialized from `handle`. Engine-side
/// failures with no underlying host exception (bridge serialization
/// faults, missing-bridge errors, etc.) MUST use a different
/// variant — they are not host-language errors and have nothing to
/// rehydrate. Such SDK/bridge faults route through fatal
/// [`VmInternalError::BridgeFailure`].
#[error("host callable error: {message} [class={class_name}, lang={language:?}]")]
HostCallable {
class_name: String,
message: String,
traceback: Option<String>,
language: Option<String>,
/// Required: handle to the originating host exception object
/// (registered in the per-bridge host-value table at the point
/// of the throw). Materialized into the BAML class's `_handle`
/// field on the way out so the originating runtime can resolve
/// it back to the original native exception.
handle: std::sync::Arc<bex_resource_types::HostValueArc>,
},
}
impl VmBamlError {
/// Map this `baml.errors.*` value to its contract-level
/// [`SysOpErrorCategory`] — the finite set of categories that sysop
/// `#[throws(...)]` annotations reference.View on GitHub (pinned to bd85ce9dee)
Solutions
- Inspect class_name/message/traceback to identify the host exception, and fix the bug in the host function itself.
- On the host side, catch the exception at the callable boundary if it should be handled inside BAML instead of propagating.
- Use the handle to rehydrate the original exception in the host runtime for full stack details.
- Ensure the bridge/SDK versions match between host language and BAML runtime.
Example fix
# before: host callable raises -> host callable error: bad input [class=ValueError, lang=Python]
def my_tool(x):
return int(x) # throws on bad input
# after: validate at the boundary
def my_tool(x):
try:
return int(x)
except ValueError:
return "invalid input" Defensive patterns
Strategy: try-catch
Validate before calling
# Host side (Python): wrap callables that may throw
def safe_tool(fn):
def wrapper(*a, **kw):
try:
return fn(*a, **kw)
except Exception as e:
return {"__tool_error__": type(e).__name__, "msg": str(e)}
return wrapper Try / catch
match vm_result {
Err(BexError::HostCallable { class_name, message, traceback, handle, .. }) => {
let host_exc = rehydrate_exception(handle)?;
eprintln!("host error {}: {}\n{:?}", class_name, message, traceback);
}
other => other?,
} Prevention
- Validate inputs inside host callables before doing work.
- Catch expected exceptions at the callable boundary in the host language.
- Keep bridge/SDK versions in sync between host runtime and BAML.
- Distinguish host exceptions from bridge faults (bridge faults use VmInternalError::BridgeFailure).
When it happens
Trigger: A host function/class method invoked from BAML raised an exception; the bridge captured the host exception (e.g. a Python ValueError or JS TypeError) and serialized it into this VM error, keeping a handle to the original object.
Common situations: BAML calling a custom tool/function written in Python or TS that throws; host-side dependency failures (network libs, file IO) surfacing inside BAML execution; version mismatches between host SDK and BAML runtime altering callable behavior.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- compilation failed: {e:?}
- failed to serialize BAML bytecode: {e}
- no `.baml` files found in {}
- could not find packaged playground assets. For local debuggi
- `--file` and `--project` are mutually exclusive; `--file` al
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/1567d11d15479ac6.
Report an issue: GitHub.