BoundaryML/baml · error · EngineError
Cannot convert object of type
Error message
Cannot convert object of type {type_name} What it means
The engine was asked to convert a BAML object into a host/external representation but the object's type has no conversion defined. The message names the offending BAML type (type_name). It indicates a mismatch between what the host expects and what the VM produced.
Solutions
- Return a convertible type (primitive, list, map) from the BAML function instead of the custom object
- Convert the object to a plain representation inside BAML before returning
- Check type_name and add/extend conversion support in the host integration
- Upgrade the engine — newer versions may support converting this type
Example fix
// before (BAML)
function f() { return MyClass(...) } // object not convertible
// after
function f() { return MyClass(...).to_dict() } // or return fields individually Defensive patterns
Strategy: type-guard
Validate before calling
fn convertible(v: &BexExternalValue) -> bool {
matches!(v, BexExternalValue::Null(_) | BexExternalValue::Int(_) | BexExternalValue::String(_) | BexExternalValue::List(_) | BexExternalValue::Map(_))
} Type guard
fn is_plain_value(v: &BexExternalValue) -> bool {
!matches!(v, BexExternalValue::Object(o) if o.is_class_instance())
} Prevention
- Return only primitives/lists/maps from BAML entry points
- Serialize objects to plain data inside BAML before crossing the boundary
- Check supported conversion types for your engine version
When it happens
Trigger: Calling APIs that export BAML values to the host (e.g. serialization/conversion entry points) with an object type lacking a converter — e.g. passing a class instance or opaque object where only primitives/maps are supported.
Common situations: Returning custom class instances from BAML functions to a host that expects JSON-able values; version changes adding new value kinds before converters exist.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- ai.Prompt._data must contain baml_builtins2::PromptAst
- array access on non-list at
- array access should be either map or array.
- array assignment on non-list value at
- assert condition must be boolean
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/a5ffbfee63d68fc9.
Report an issue: GitHub.
Appendix: source
Thrown at baml_language/crates/bex_engine/src/lib.rs:842
source: bex_vm::errors::VmInternalError,
trace: Vec<bex_vm::StackFrame>,
},
/// Either a BAML panic or a BAML error value.
#[error("{}", format_unhandled_throw(value, trace))]
UnhandledThrow {
value: Box<BexExternalValue>,
trace: Vec<bex_vm::StackFrame>,
},
/// Clean process-termination request from `baml.sys.exit(code)`.
/// The caller is expected to honor this as the process exit code.
/// BAML `int` is `i64`, so the signal carries the full value; the
/// caller clamps into its shell's range (typically 0..=255 on Unix).
#[error("baml.sys.exit({code})")]
Exit { code: i64 },
#[error("Cannot convert object of type {type_name}")]
CannotConvert { type_name: String },
#[error("Type mismatch: {message}")]
TypeMismatch { message: String },
#[error("Schema inconsistency: {message}")]
SchemaInconsistency { message: String },
#[cfg(feature = "heap_debug")]
#[error("Snapshot not possible for type: {type_name}")]
CannotSnapshot { type_name: String },
#[error("A function call with ID {call_id} is already in progress")]
DuplicateCallId { call_id: CallId },
#[error("Package initialization failed: {0}")]
InitFailed(String),
View on GitHub (pinned to bd85ce9dee)