{"record":{"id":"a0883adb0a0a5176","repo":"BoundaryML/baml","slug":"sentinel-cannot-be-serialized","errorCode":null,"errorMessage":"Sentinel cannot be serialized","messagePattern":"Sentinel cannot be serialized","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"baml_language/crates/bex_vm_types/src/types/object.rs","lineNumber":270,"sourceCode":"            Self::Float(v) => ObjectWire::Float(*v),\n            Self::Future(v) => ObjectWire::Future(v.clone()),\n            Self::UnscheduledFuture(v) => ObjectWire::UnscheduledFuture(v.clone()),\n            Self::Type(v) => ObjectWire::Type(Box::new(v.ty.clone())),\n            Self::RustData(_) => {\n                return Err(std::io::Error::new(\n                    std::io::ErrorKind::InvalidData,\n                    \"RustData cannot be serialized\",\n                ));\n            }\n            Self::HostClosure(_) => {\n                return Err(std::io::Error::new(\n                    std::io::ErrorKind::InvalidData,\n                    \"HostClosure cannot be serialized\",\n                ));\n            }\n            #[cfg(feature = \"heap_debug\")]\n            Self::Sentinel(_) => {\n                return Err(std::io::Error::new(\n                    std::io::ErrorKind::InvalidData,\n                    \"Sentinel cannot be serialized\",\n                ));\n            }\n        };\n        proxy.serialize(writer)\n    }\n}\n\nimpl BorshDeserialize for Object {\n    fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {\n        let proxy = ObjectWire::deserialize_reader(reader)?;\n        Ok(match proxy {\n            ObjectWire::Function(v) => Self::Function(v),\n            ObjectWire::Interface(v) => Self::Interface(v),\n            ObjectWire::Package(v) => Self::Package(v),\n            ObjectWire::ImplRule(v) => Self::ImplRule(v),\n            ObjectWire::Class(v) => Self::Class(v),","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_vm_types/src/types/object.rs#L252-L288","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nfor obj in heap.objects() {\n    obj.serialize(&mut out)?;\n}\n// after\nfor obj in heap.objects() {\n    if matches!(obj, Object::Sentinel(_)) { continue; }\n    obj.serialize(&mut out)?;\n}","handlingStrategy":"validation","validationCode":"fn is_serializable(obj: &Object) -> bool {\n    !matches!(obj, Object::Sentinel(_) | Object::HostClosure(_))\n}","typeGuard":"fn as_serializable(obj: &Object) -> Option<&Object> {\n    match obj {\n        Object::Sentinel(_) | Object::HostClosure(_) => None,\n        _ => Some(obj),\n    }\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["serialization","rust","vm-internals","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}