BoundaryML/baml · error · Error
failed to decode {kind}: {message}
Error message
failed to decode {kind}: {message} What it means
`Error::Decode` wraps a Borsh deserialization failure that occurred after the artifact envelope (magic, header, hash) validated successfully but the payload bytes could not be interpreted as the expected type `T`. The inner `message` describes the deserialization problem.
Source
Thrown at baml_language/crates/baml_artifact/src/lib.rs:146
expected: ArtifactKind,
actual: ArtifactKind,
},
#[error("{kind} artifact failed integrity validation")]
InvalidPayloadHash { kind: ArtifactKind },
#[error(
"{kind}: toolchain {artifact_fingerprint} / format {artifact_format}; this runtime: {runtime_fingerprint} / format {runtime_format} — {remediation}"
)]
Incompatible {
kind: ArtifactKind,
artifact_fingerprint: String,
artifact_format: u32,
runtime_fingerprint: &'static str,
runtime_format: u32,
remediation: &'static str,
},
#[error("failed to encode {kind}: {message}")]
Encode { kind: ArtifactKind, message: String },
#[error("failed to decode {kind}: {message}")]
Decode { kind: ArtifactKind, message: String },
}
/// Serialize `value` and wrap it in a versioned artifact envelope.
pub fn encode<T: BorshSerialize>(kind: ArtifactKind, value: &T) -> Result<Vec<u8>, Error> {
let payload = borsh::to_vec(value).map_err(|error| Error::Encode {
kind,
message: error.to_string(),
})?;
encode_payload(kind, &payload)
}
/// Encode a value with an explicit artifact format for cross-crate skew tests.
#[cfg(feature = "test-support")]
#[doc(hidden)]
pub fn encode_with_format_for_test<T: BorshSerialize>(
artifact_format: u32,
kind: ArtifactKind,View on GitHub (pinned to bd85ce9dee)
Solutions
- Regenerate the artifact with the toolchain matching the runtime so the payload schema matches the decode type.
- Check the inner `message` to find which field offsets/types diverge and align the Rust type with the writer's schema.
- Ensure the format-version constant is bumped whenever the serialized struct changes, so stale artifacts are rejected with Incompatible instead of Decode errors.
- Verify you are decoding with the same type `T` the artifact was encoded with.
Example fix
// before let manifest: ManifestV2 = decode(ManifestKind::Ir, &bytes)?; // payload written as V1 // after let manifest: ManifestV1 = decode(ManifestKind::Ir, &bytes)?; // decode with the writer's schema
Defensive patterns
Strategy: try-catch
Try / catch
// Rust
match baml_artifact::decode::<Manifest>(&bytes) {
Ok(manifest) => use(manifest),
Err(baml_artifact::Error::Decode { message, .. }) => {
eprintln!("artifact payload unreadable: {message} — regenerate with matching toolchain");
}
Err(e) => return Err(e.into()),
} Prevention
- Bump the artifact format version whenever serialized structs change.
- Decode with the same type the artifact was encoded with.
- Add round-trip encode/decode tests to the pipeline.
- Regenerate artifacts after any toolchain or schema upgrade.
When it happens
Trigger: Calling the crate's decode path with a type `T: BorshDeserialize` whose in-memory layout expectation does not match the serialized payload — e.g., decoding with a different struct version than was encoded.
Common situations: A struct gained/lost fields between toolchain versions while the artifact format version wasn't bumped; decoding the payload with the wrong type parameter; artifacts produced by a mismatched generator reaching an updated runtime.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to encode {kind}: {message}
- {kind} artifact is truncated
- invalid {kind} artifact header: {message}
- invalid package interface: {message}
- variant `{}` requires an explicit discriminant to stabilize
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/c7672cbeee92c7ea.
Report an issue: GitHub.