{"record":{"id":"f2ae8e555c404dc8","repo":"nautechsystems/nautilus_trader","slug":"execution-verification-manifest-identity-changed","errorCode":null,"errorMessage":"Execution verification manifest identity changed","messagePattern":"Execution verification manifest identity changed","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"critical","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":3712,"sourceCode":"        );\n        let chain_id =\n            i32::try_from(chain_id).context(\"Verification chain ID exceeds PostgreSQL INTEGER\")?;\n        let current = sqlx::query_as::<_, (String, String, i64, i64)>(\n            \"\n            SELECT manifest_version, manifest_digest, next_canonical_nonce, revision\n            FROM execution_verification_nonce\n            WHERE chain_id = $1 AND wallet_address = $2\n            \",\n        )\n        .bind(chain_id)\n        .bind(wallet_address)\n        .fetch_optional(&self.pool)\n        .await\n        .context(\"failed to load execution verification nonce position\")?;\n        let Some((stored_version, stored_digest, nonce, revision)) = current else {\n            return Ok(None);\n        };\n        anyhow::ensure!(\n            stored_version == manifest_version && stored_digest == manifest_digest,\n            \"Execution verification manifest identity changed\"\n        );\n        let row = sqlx::query_as::<_, (i64, String, String, i64, Option<String>, String)>(\n            \"\n            SELECT number, hash, parent_hash, timestamp, base_fee_per_gas, manifest_digest\n            FROM execution_verified_finalized_header\n            WHERE chain_id = $1 AND wallet_address = $2\n            ORDER BY number DESC\n            LIMIT 1\n            \",\n        )\n        .bind(chain_id)\n        .bind(wallet_address)\n        .fetch_optional(&self.pool)\n        .await\n        .context(\"failed to load verified finalized header tip\")?\n        .ok_or_else(|| anyhow::anyhow!(\"Verified finalized header ledger is empty\"))?;","sourceCodeStart":3694,"sourceCodeEnd":3730,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/cache/database.rs#L3694-L3730","documentation":"Raised in database.rs:3712 when the persisted verification nonce row's manifest_version or manifest_digest do not match the digest/version of the manifest the caller is using. The manifest is the identity of the verification rules and contract set; a mismatch means the stored verification state was produced under a different manifest and is not interchangeable with the current one.","triggerScenarios":"Calling load_execution_verification_position with manifest_version/manifest_digest arguments that differ from the (manifest_version, manifest_digest) stored in execution_verification_nonce for the given chain_id and wallet_address.","commonSituations":"Changing the verification manifest (adding/changing verified contracts or rules) without re-bootstrapping the wallet's verification state; pointing the node at a database initialized for a different deployment configuration; wallet previously verified under a different manifest revision.","solutions":["Re-bootstrap the verification state for this wallet/chain so the stored manifest matches the current one.","Verify the manifest version and digest your deployment passes match the values used when the database was initialized.","If the manifest change was accidental, revert the manifest configuration to the digest stored in execution_verification_nonce.","Wipe/rotate verification state for the affected wallet deliberately (with the prior nonce accounted for) rather than editing rows ad hoc."],"exampleFix":"// before: manifest config edited -> digest mismatch\nlet pos = db.load_execution_verification_position(chain, wallet, \"v1\", &old_digest).await;\n// after: pass the manifest identity that matches the stored state, or re-bootstrap\nlet (ver, digest) = current_manifest_identity();\nassert_eq!((ver, digest), stored_manifest_identity(&db, chain, wallet)?);\nlet pos = db.load_execution_verification_position(chain, wallet, &ver, &digest).await?;","handlingStrategy":"validation","validationCode":"let stored: Option<(String, String)> = sqlx::query_as(\n    \"SELECT manifest_version, manifest_digest FROM execution_verification_nonce \\\n     WHERE chain_id = $1 AND wallet_address = $2\",\n).bind(chain_id).bind(wallet).fetch_optional(&pool).await?;\nif let Some((v, d)) = stored {\n    assert_eq!((v.as_str(), d.as_str()), (manifest_version, manifest_digest),\n        \"manifest identity drifted; re-bootstrap required\");\n}","typeGuard":null,"tryCatchPattern":"match load_position(...).await {\n    Err(e) if e.to_string().contains(\"manifest identity changed\") => {\n        // halt verification for this wallet; re-bootstrap under the new manifest\n    },\n    other => other?,\n}","preventionTips":["Treat the verification manifest as immutable per deployment; version it explicitly","Persist the new manifest digest and re-bootstrap atomically when the manifest changes","Never share one database between deployments with different manifests"],"tags":["database","integrity","verification","manifest"],"backgroundTag":"checksum-mismatch","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}