BoundaryML/baml · error
Sentinel cannot be serialized
Error message
Sentinel cannot be serialized
What it means
The VM value serializer in bex_vm_types refuses to serialize an Object variant carrying a Sentinel. Sentinel objects are internal bookkeeping markers (e.g. heap-debug probes), not real data, so a serialized Sentinel could never be deserialized into a meaningful value. Serialization is deliberately made to fail loudly with InvalidData rather than silently emit a lossy byte stream. The same guard covers HostClosure, which cannot cross the wire either.
Source
Thrown at baml_language/crates/bex_vm_types/src/types/object.rs:270
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",
));
}
};
proxy.serialize(writer)
}
}
impl BorshDeserialize for Object {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
let proxy = ObjectWire::deserialize_reader(reader)?;
Ok(match proxy {
ObjectWire::Function(v) => Self::Function(v),
ObjectWire::Interface(v) => Self::Interface(v),
ObjectWire::Package(v) => Self::Package(v),
ObjectWire::ImplRule(v) => Self::ImplRule(v),
ObjectWire::Class(v) => Self::Class(v),View on GitHub (pinned to bd85ce9dee)
Solutions
- Filter out or unwrap Sentinel entries before serializing (serialize only real payload objects).
- If Sentinel is legitimately needed, serialize a lightweight placeholder (e.g. unit/null marker) and reconstruct it on deserialize instead of routing it into this arm.
- Disable the heap_debug feature for production serialization paths, where the Sentinel arm does not exist.
- If you only need the serialized payload, call the inner proxy's serialize directly, skipping the enclosing object wrapper.
Example fix
// before
for obj in heap.objects() {
obj.serialize(&mut out)?;
}
// after
for obj in heap.objects() {
if matches!(obj, Object::Sentinel(_)) { continue; }
obj.serialize(&mut out)?;
} Defensive patterns
Strategy: validation
Validate before calling
fn is_serializable(obj: &Object) -> bool {
!matches!(obj, Object::Sentinel(_) | Object::HostClosure(_))
} Type guard
fn as_serializable(obj: &Object) -> Option<&Object> {
match obj {
Object::Sentinel(_) | Object::HostClosure(_) => None,
_ => Some(obj),
}
} Prevention
- Filter Sentinel and HostClosure objects out of any heap snapshot before serializing.
- Do not enable the heap_debug feature on serialization-sensitive builds.
- Add a round-trip test that serializes every Object variant you produce in production.
When it happens
Trigger: Calling serialize on an Object::Sentinel(_) value — typically via object.serialize(writer) or a Value serialization that reaches this match arm in types/object.rs. Only compiled with feature = "heap_debug". Any heap walk or debug dump that accidentally includes Sentinel objects and pipes them through the serialization path triggers it.
Common situations: Debug builds with the heap_debug feature enabled where a heap snapshot/serializer walks all objects and does not filter internal sentinels; tooling that serializes whole VM heaps or object graphs for inspection; tests that put a sentinel marker inside an object field and then round-trip the value.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- honest interface fragment for `{}` failed to serialize: {e}
- PackageInterface artifact serialization into Vec is infallib
- invalid package interface: {message}
- Failed to serialize request result: {0}
- variant `{}` requires an explicit discriminant to stabilize
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/a0883adb0a0a5176.
Report an issue: GitHub.