{"record":{"id":"96448bc1e48b2d8a","repo":"nautechsystems/nautilus_trader","slug":"validated-manifest-serialization-is-infallible","errorCode":null,"errorMessage":"validated manifest serialization is infallible","messagePattern":"validated manifest serialization is infallible","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/rpc/verification.rs","lineNumber":739,"sourceCode":"                    }\n                    VerificationOutcome::Disagreement(failure) => {\n                        return VerificationOutcome::Disagreement(failure);\n                    }\n                    VerificationOutcome::Unavailable(failure) => {\n                        return VerificationOutcome::Unavailable(failure);\n                    }\n                    VerificationOutcome::Retryable(failure) => {\n                        return VerificationOutcome::Retryable(failure);\n                    }\n                    VerificationOutcome::LocallyInvalid(failure) => {\n                        return VerificationOutcome::LocallyInvalid(failure);\n                    }\n                }\n            }\n        }\n\n        let normalized_value_digest = keccak256(\n            serde_json::to_vec(manifest).expect(\"validated manifest serialization is infallible\"),\n        );\n        VerificationOutcome::Verified(Verified {\n            value: (),\n            read: VerificationRead::DeploymentIdentity,\n            provider_ids: self.provider_ids(),\n            normalized_value_digest,\n        })\n    }\n\n    pub(crate) async fn verify_storage(\n        &self,\n        address: &Address,\n        slot: &B256,\n        block: u64,\n    ) -> VerificationOutcome<B256> {\n        let (a, b, c) = tokio::join!(\n            self.sources[0].storage_at(address, slot, block),\n            self.sources[1].storage_at(address, slot, block),","sourceCodeStart":721,"sourceCodeEnd":757,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/rpc/verification.rs#L721-L757","documentation":"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.","triggerScenarios":"Only reachable if BlockchainDeploymentManifest (or a nested type) gains fields that serde_json cannot serialize, or a custom Serialize impl returns an error.","commonSituations":"Practically never hit in application code; seen by maintainers after changing manifest types, especially adding HashMap keys that are not strings.","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"],"exampleFix":"// before\n// struct with non-string map key breaks to_vec\ncontracts_index: HashMap<Address, Contract>,\n// after\ncontracts_index: BTreeMap<String, Contract>, // JSON-serializable keys","handlingStrategy":"try-catch","validationCode":"let digest = serde_json::to_vec(manifest)\n    .map_err(|e| anyhow::anyhow!(\"manifest serialization failed: {e}\"))?;","typeGuard":null,"tryCatchPattern":"match serde_json::to_vec(manifest) {\n    Ok(bytes) => compute_digest(bytes),\n    Err(e) => log::error!(\"manifest serialization invariant broken: {e}\"),\n}","preventionTips":["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"],"tags":["panic","invariant","serialization","serde"],"backgroundTag":"internal-invariant-violation","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}