nautechsystems/nautilus_trader · error
validated manifest serialization is infallible
Error message
validated manifest serialization is infallible
What it means
After all contract checks pass, the manifest is serialized with serde_json::to_vec to compute a keccak digest of the verified state. serde_json serialization of an in-memory struct cannot fail, so expect() encodes that invariant. A panic here means non-serializable data (e.g. a map with non-string keys added to the manifest type) broke the guarantee.
Source
Thrown at crates/adapters/blockchain/src/rpc/verification.rs:739
}
VerificationOutcome::Disagreement(failure) => {
return VerificationOutcome::Disagreement(failure);
}
VerificationOutcome::Unavailable(failure) => {
return VerificationOutcome::Unavailable(failure);
}
VerificationOutcome::Retryable(failure) => {
return VerificationOutcome::Retryable(failure);
}
VerificationOutcome::LocallyInvalid(failure) => {
return VerificationOutcome::LocallyInvalid(failure);
}
}
}
}
let normalized_value_digest = keccak256(
serde_json::to_vec(manifest).expect("validated manifest serialization is infallible"),
);
VerificationOutcome::Verified(Verified {
value: (),
read: VerificationRead::DeploymentIdentity,
provider_ids: self.provider_ids(),
normalized_value_digest,
})
}
pub(crate) async fn verify_storage(
&self,
address: &Address,
slot: &B256,
block: u64,
) -> VerificationOutcome<B256> {
let (a, b, c) = tokio::join!(
self.sources[0].storage_at(address, slot, block),
self.sources[1].storage_at(address, slot, block),View on GitHub (pinned to 18893faf8b)
Solutions
- Check recent changes to BlockchainDeploymentManifest and its Serialize impls for non-JSON-serializable types (e.g. non-string map keys)
- Ensure all nested map types use string keys
- Run the manifest round-trip test (to_vec then from_slice) to catch serialization failures
- If hit in a release build, report it — it indicates a broken invariant in the crate
Example fix
// before // struct with non-string map key breaks to_vec contracts_index: HashMap<Address, Contract>, // after contracts_index: BTreeMap<String, Contract>, // JSON-serializable keys
Defensive patterns
Strategy: try-catch
Validate before calling
let digest = serde_json::to_vec(manifest)
.map_err(|e| anyhow::anyhow!("manifest serialization failed: {e}"))?; Try / catch
match serde_json::to_vec(manifest) {
Ok(bytes) => compute_digest(bytes),
Err(e) => log::error!("manifest serialization invariant broken: {e}"),
} Prevention
- Keep manifest fields JSON-serializable (string map keys only)
- Add a serialize round-trip test for BlockchainDeploymentManifest
- Never add custom Serialize impls that can fail
When it happens
Trigger: Only reachable if BlockchainDeploymentManifest (or a nested type) gains fields that serde_json cannot serialize, or a custom Serialize impl returns an error.
Common situations: Practically never hit in application code; seen by maintainers after changing manifest types, especially adding HashMap keys that are not strings.
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
- Close command should not be drained
- Flush command should not be drained
- Order invariant violated: first event must be OrderInitializ
- Failed to serialize config value: {e}
- serialized order did not contain an object core
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/96448bc1e48b2d8a.
Report an issue: GitHub.