{"record":{"id":"1c5668f4e74b724a","repo":"BoundaryML/baml","slug":"future-cannot-be-serialized","errorCode":null,"errorMessage":"Future cannot be serialized","messagePattern":"Future cannot be serialized","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"baml_language/crates/bex_vm_types/src/types/future.rs","lineNumber":121,"sourceCode":"    /// `Ok(())` is \"look at `state` for the actual outcome\"; `Err(_)`\n    /// carries an unrecoverable engine error for surfacing through the\n    /// engine's `Await` resume path. It also carries weak Session eval leases\n    /// that cancellation releases before waking the awaiter; keeping both in\n    /// one Arc preserves `Future`'s interpreter-hot-loop size budget.\n    settlement: Arc<FutureSettlement>,\n}\n\n// SAFETY: All access to `value` is gated by the Acquire/Release handshake\n// on `state` and the single-writer invariant enforced by the\n// `FutureManager`'s state mutex.\nunsafe impl Send for Future {}\nunsafe impl Sync for Future {}\n\n// Futures are runtime-only; they never appear in a compiled Program. Reject\n// serialization explicitly so a malformed program fails fast.\nimpl BorshSerialize for Future {\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            \"Future cannot be serialized\",\n        ))\n    }\n}\n\nimpl BorshDeserialize for Future {\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            \"Future cannot be deserialized\",\n        ))\n    }\n}\n\n// `UnscheduledFuture` is a runtime spawn-request slot — same lifecycle\n// shape as `Future`, never appears in a compiled `Program`. The pack\n// envelope (`baml_exec::PackEnvelope`) serializes the bytecode + the","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_vm_types/src/types/future.rs#L103-L139","documentation":"Future's BorshSerialize impl is deliberately a hard failure: Futures are runtime-only values that never appear in a compiled Program. Serialization is rejected explicitly so a malformed program fails fast instead of silently encoding an unusable runtime handle.","triggerScenarios":"Serializing a VM value graph or structure that contains a Future (e.g. attempting to persist runtime state with pending async results, or a compiler/VM bug placing a Future into serialized program data).","commonSituations":"Caching serialized VM state that includes in-flight futures; trying to snapshot/serialize the raw runtime value instead of its resolved result; internal bugs routing runtime values into the compiled artifact path.","solutions":["Await the Future and serialize its resolved result instead of the Future itself.","Exclude runtime-only values (futures, heap pointers) from anything you serialize; only compiled Program types are serializable.","If this fires during normal program compilation/serialization, report it — a runtime-only Future leaked into the serialized Program, which is an invariant violation.","Restructure your snapshotting to store only plain data (strings, numbers, completed values)."],"exampleFix":"// before: serializing a runtime value holding a Future\nlet blob = borsh::to_vec(&runtime_value_with_future)?;\n\n// after: resolve first, then serialize the result\nlet resolved = vm.await_future(runtime_value_with_future)?;\nlet blob = borsh::to_vec(&resolved)?;","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Rust: never serialize unresolved futures — check first\nfn is_resolved(f: &FutureState) -> bool {\n    matches!(f, FutureState::Ready(_))\n}","tryCatchPattern":null,"preventionTips":["Await futures before serializing anything downstream of them.","Exclude runtime-only values (futures, heap pointers) from serialized payloads.","Serialize only completed plain data values or compiled Program types.","Report occurrences during normal compilation — they indicate an internal invariant violation."],"tags":["borsh","serialization","future","async","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"}