{"record":{"id":"ac8a78656e45b0e0","repo":"BoundaryML/baml","slug":"heapptr-cannot-be-deserialized-runtime-pointer-leaked-into","errorCode":null,"errorMessage":"HeapPtr cannot be deserialized: runtime pointer leaked into serialized data","messagePattern":"HeapPtr cannot be deserialized: runtime pointer leaked into serialized data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"baml_language/crates/bex_vm_types/src/heap_ptr.rs","lineNumber":172,"sourceCode":"// envelope) — the addresses are meaningless outside the originating\n// process, and a deserialized non-null `HeapPtr` would be undefined\n// behavior on first deref. The borsh impls below therefore *fail* at the\n// boundary instead of round-tripping to `null()`: every type the compiler\n// actually puts into a serialized `Program` (`Object::{Function, Class,\n// Enum, String}`) is HeapPtr-free, so any path that does encounter one\n// reflects a real bug we want to surface immediately rather than mask.\nimpl BorshSerialize for HeapPtr {\n    fn serialize<W: std::io::Write>(&self, _writer: &mut W) -> std::io::Result<()> {\n        Err(std::io::Error::new(\n            std::io::ErrorKind::InvalidData,\n            \"HeapPtr is a runtime-only pointer and must not be serialized\",\n        ))\n    }\n}\n\nimpl BorshDeserialize for HeapPtr {\n    fn deserialize_reader<R: std::io::Read>(_reader: &mut R) -> std::io::Result<Self> {\n        Err(std::io::Error::new(\n            std::io::ErrorKind::InvalidData,\n            \"HeapPtr cannot be deserialized: runtime pointer leaked into serialized data\",\n        ))\n    }\n}\n\nimpl PartialEq for HeapPtr {\n    fn eq(&self, other: &Self) -> bool {\n        self.ptr == other.ptr\n    }\n}\n\nimpl Eq for HeapPtr {}\n\nimpl Default for HeapPtr {\n    fn default() -> Self {\n        Self::null()\n    }","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_vm_types/src/heap_ptr.rs#L154-L190","documentation":"HeapPtr's BorshDeserialize impl is intentionally a hard failure: deserializing would have to fabricate a runtime heap pointer from stored bytes, which is never valid. Encountering this means runtime pointer data leaked into a serialized payload — a real bug that must fail fast rather than reconstruct a dangling pointer.","triggerScenarios":"Calling borsh deserialization on a byte blob whose structure contains a HeapPtr-typed field; loading a corrupted or hand-crafted serialized Program where a runtime pointer was encoded.","commonSituations":"Loading stale/foreign serialized artifacts produced by buggy tooling; deserializing into the wrong type so bytes are interpreted as a HeapPtr; tampering or corruption in shipped program files.","solutions":["Regenerate the serialized Program from the compiler with a correct, HeapPtr-free build.","Verify you are deserializing with the matching type/schema and library version used at serialization time.","If the artifact is third-party or hand-edited, obtain it from a trusted source and re-check its integrity.","Report it if normal compiled programs trigger this — it indicates a compiler bug leaking runtime pointers into serialized output."],"exampleFix":"// before: decoding into a struct with a HeapPtr field\nlet snap: Snapshot = borsh::from_reader(&mut r)?; // Snapshot { obj: HeapPtr }\n\n// after: decode into the HeapPtr-free Program object types\nlet prog: Program = borsh::from_reader(&mut r)?;","handlingStrategy":"type-guard","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only deserialize Program artifacts produced by the same compiler/runtime version.","Never decode arbitrary bytes into structs containing HeapPtr fields.","Verify artifact integrity (checksums) when transferring serialized programs.","Treat any hit as corruption/bug — deserialized data must never fabricate heap pointers."],"tags":["borsh","deserialization","heap-pointer","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}