BoundaryML/baml · critical
Future cannot be serialized
Error message
Future cannot be serialized
What it means
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.
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).
Example fix
// before: serializing a runtime value holding a Future let blob = borsh::to_vec(&runtime_value_with_future)?; // after: resolve first, then serialize the result let resolved = vm.await_future(runtime_value_with_future)?; let blob = borsh::to_vec(&resolved)?;
Defensive patterns
Strategy: type-guard
Type guard
// Rust: never serialize unresolved futures — check first
fn is_resolved(f: &FutureState) -> bool {
matches!(f, FutureState::Ready(_))
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- HeapPtr is a runtime-only pointer and must not be serialized
- failed to decode
- failed to encode
- Future cannot be deserialized
- Future short-circuited above
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/1c5668f4e74b724a.
Report an issue: GitHub.
Appendix: source
Thrown at baml_language/crates/bex_vm_types/src/types/future.rs:121
/// `Ok(())` is "look at `state` for the actual outcome"; `Err(_)`
/// carries an unrecoverable engine error for surfacing through the
/// engine's `Await` resume path. It also carries weak Session eval leases
/// that cancellation releases before waking the awaiter; keeping both in
/// one Arc preserves `Future`'s interpreter-hot-loop size budget.
settlement: Arc<FutureSettlement>,
}
// SAFETY: All access to `value` is gated by the Acquire/Release handshake
// on `state` and the single-writer invariant enforced by the
// `FutureManager`'s state mutex.
unsafe impl Send for Future {}
unsafe impl Sync for Future {}
// Futures are runtime-only; they never appear in a compiled Program. Reject
// serialization explicitly so a malformed program fails fast.
impl BorshSerialize for Future {
fn serialize<W: std::io::Write>(&self, _writer: &mut W) -> std::io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Future cannot be serialized",
))
}
}
impl BorshDeserialize for Future {
fn deserialize_reader<R: std::io::Read>(_reader: &mut R) -> std::io::Result<Self> {
Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Future cannot be deserialized",
))
}
}
// `UnscheduledFuture` is a runtime spawn-request slot — same lifecycle
// shape as `Future`, never appears in a compiled `Program`. The pack
// envelope (`baml_exec::PackEnvelope`) serializes the bytecode + theView on GitHub (pinned to bd85ce9dee)