BoundaryML/baml · error

RustData cannot be serialized

Error message

RustData cannot be serialized

What it means

`Object::RustData` wraps an opaque host-side Rust value that has no Borsh wire representation, so `Object`'s `BorshSerialize` returns `Err(InvalidData)` with this message when it encounters that variant. Any object pool containing host data cannot be turned into a pack; the library fails fast rather than silently dropping the payload.

Source

Thrown at baml_language/crates/bex_vm_types/src/types/object.rs:257

            Self::Cell(v) => ObjectWire::Cell(v.clone()),
            Self::String(v) => ObjectWire::String(v.to_string()),
            Self::Bigint(v) => ObjectWire::Bigint((**v).clone()),
            Self::Uint8Array(v) => ObjectWire::Uint8Array(v.lock().clone()),
            Self::Array(v) => ObjectWire::Array(v.element_ty.clone(), v.data.lock().clone()),
            Self::Map(v) => ObjectWire::Map(
                v.key_ty.clone(),
                v.value_ty.clone(),
                v.to_index_map()
                    .into_iter()
                    .map(|(k, v)| (k.to_string(), v))
                    .collect(),
            ),
            Self::Float(v) => ObjectWire::Float(*v),
            Self::Future(v) => ObjectWire::Future(v.clone()),
            Self::UnscheduledFuture(v) => ObjectWire::UnscheduledFuture(v.clone()),
            Self::Type(v) => ObjectWire::Type(Box::new(v.ty.clone())),
            Self::RustData(_) => {
                return Err(std::io::Error::new(
                    std::io::ErrorKind::InvalidData,
                    "RustData cannot be serialized",
                ));
            }
            Self::HostClosure(_) => {
                return Err(std::io::Error::new(
                    std::io::ErrorKind::InvalidData,
                    "HostClosure cannot be serialized",
                ));
            }
            #[cfg(feature = "heap_debug")]
            Self::Sentinel(_) => {
                return Err(std::io::Error::new(
                    std::io::ErrorKind::InvalidData,
                    "Sentinel cannot be serialized",
                ));
            }
        };

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Remove `RustData` values from the value graph before serializing (GC/collect or exclude runtime heap regions).
  2. Represent host data as a registered handle/id (e.g. an integer foreign-object id) that survives serialization instead of embedding the Rust value.
  3. If you control the injection site, only pass plain serializable types (strings, arrays, maps, ints) across the host boundary.

Example fix

// before
vm.call_host("db", RustData::new(my_pool_connection));
let pack = PackEnvelope::new(program, vm.heap()); // io::Error: RustData cannot be serialized
// after: pass an id, keep the Rust value host-side
let handle = host_registry.insert(my_pool_connection);
vm.call_host("db", Value::Int(handle as i64));
let pack = PackEnvelope::new(program, vm.heap());
Defensive patterns

Strategy: validation

Validate before calling

// before serializing an object graph
fn graph_is_serializable(values: &[Value]) -> bool {
    values.iter().all(|v| !matches!(
        v,
        Value::Object(o) if matches!(&*o.borrow(), Object::RustData(_) | Object::HostClosure(_))
    ))
}

Type guard

fn is_rust_data(o: &Object) -> bool {
    matches!(o, Object::RustData(_))
}

Prevention

When it happens

Trigger: Serializing an `Object` (directly or via `Value`/object-pool/pack serialization) whose variant is `Self::RustData(_)` — i.e. a live VM heap that holds an opaque host object.

Common situations: Calling a host function that injected a Rust value into the VM, then attempting to snapshot/persist the heap or pack the program while that value is still reachable; including host objects in a module-level constant; running a pack-export tool against a live session heap.

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/8fe55d69839366b0. Report an issue: GitHub.