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

  1. Check recent changes to BlockchainDeploymentManifest and its Serialize impls for non-JSON-serializable types (e.g. non-string map keys)
  2. Ensure all nested map types use string keys
  3. Run the manifest round-trip test (to_vec then from_slice) to catch serialization failures
  4. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/96448bc1e48b2d8a. Report an issue: GitHub.