{"record":{"id":"af2fc4bfa606e260","repo":"nautechsystems/nautilus_trader","slug":"validated-proxy-target-hash","errorCode":null,"errorMessage":"validated proxy target hash","messagePattern":"validated proxy target hash","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/rpc/verification.rs","lineNumber":681,"sourceCode":"                        );\n                    }\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                let target =\n                    Address::from_str(&proxy.target_address).expect(\"validated proxy target\");\n                let target_hash =\n                    B256::from_str(&proxy.target_code_hash).expect(\"validated proxy target hash\");\n                match self.verify_code(&target, block).await {\n                    VerificationOutcome::Verified(verified)\n                        if !verified.value.is_empty()\n                            && keccak256(&verified.value) == target_hash => {}\n                    VerificationOutcome::Verified(_) => {\n                        return VerificationOutcome::Disagreement(\n                            self.failure(VerificationRead::DeploymentIdentity),\n                        );\n                    }\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                    }","sourceCodeStart":663,"sourceCodeEnd":699,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/rpc/verification.rs#L663-L699","documentation":"This panic occurs in verify_deployment_manifest when parsing proxy.target_code_hash into a B256 via expect(). The manifest is supposed to have been validated (well-formed hex hashes/addresses) before verification, so an unparseable value indicates the caller bypassed or defeated that validation. It is an internal invariant guard, not a runtime network error.","triggerScenarios":"Calling verify_deployment_manifest with a hand-constructed or deserialized BlockchainDeploymentManifest whose proxy.target_code_hash is empty, malformed, or not 32-byte hex (with or without 0x prefix).","commonSituations":"Loading a manifest from a hand-edited JSON file; a schema change or new manifest version not run through the validator; a proxy entry pointing at a target whose code hash was recorded as a placeholder (e.g. zeros or a transaction hash instead of a code hash).","solutions":["Run the manifest through its validation/normalization step before calling verify_deployment_manifest","Check proxy.target_code_hash: it must parse as a 32-byte hex string (e.g. via B256::from_str in a test)","Re-generate the manifest from the deployment tooling instead of hand-editing","If the validator accepts but the parser rejects, file a bug: the validator is missing a target_code_hash format check"],"exampleFix":"// before\nlet manifest: BlockchainDeploymentManifest = serde_json::from_str(&raw).unwrap();\nclient.verify_deployment_manifest(&manifest, block).await;\n// after\nlet manifest = validate_manifest(&raw)?; // rejects malformed target_code_hash early\nclient.verify_deployment_manifest(&manifest, block).await;","handlingStrategy":"validation","validationCode":"fn validate_proxy_target(proxy: &ProxyConfig) -> Result<(), String> {\n    B256::from_str(&proxy.target_code_hash)\n        .map(|_| ())\n        .map_err(|e| format!(\"invalid target_code_hash '{}': {e}\", proxy.target_code_hash))\n}","typeGuard":"fn is_valid_code_hash(s: &str) -> bool {\n    let h = s.trim_start_matches(\"0x\");\n    h.len() == 64 && h.chars().all(|c| c.is_ascii_hexdigit())\n}","tryCatchPattern":null,"preventionTips":["Always load manifests through the provided validator, never raw serde_json::from_str","Add a CI step that parses every hash/address field of deployment manifests","Treat manifests as generated artifacts; do not hand-edit"],"tags":["panic","invariant","manifest","hex-parsing"],"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"}