{"record":{"id":"ca88b8dda6cb4aa7","repo":"nautechsystems/nautilus_trader","slug":"retained-signed-intent-has-no-current-hash","errorCode":null,"errorMessage":"Retained signed intent {} has no current hash","messagePattern":"Retained signed intent (.+?) has no current hash","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":5457,"sourceCode":"                    nonce: None,\n                    transaction_hash: None,\n                    terminal_status: None,\n                    block_number: None,\n                    block_hash: None,\n                    receipt_success: None,\n                    gas_used: None,\n                    effective_gas_price: None,\n                    recover_prepared: true,\n                    decisions: vec![base_decision],\n                });\n                continue;\n            }\n\n            let nonce = intent.nonce.ok_or_else(|| {\n                anyhow::anyhow!(\"Retained signed intent {} has no nonce\", intent.id)\n            })?;\n            let current = current.ok_or_else(|| {\n                anyhow::anyhow!(\"Retained signed intent {} has no current hash\", intent.id)\n            })?;\n            let raw_transaction = authenticated.get(&current.id).ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"Retained signed intent {} has no authenticated current payload\",\n                    intent.id\n                )\n            })?;\n\n            if intent.active && nonce == next_canonical_nonce {\n                anyhow::ensure!(\n                    !matches!(intent.status.as_str(), \"finalized\" | \"reverted\"),\n                    \"Active terminal intent conflicts with the canonical nonce ledger\"\n                );\n                records.push(ExecutionVerificationMigrationRecord {\n                    intent_id: intent.id,\n                    nonce: Some(nonce),\n                    transaction_hash: Some(current.transaction_hash.clone()),\n                    terminal_status: None,","sourceCodeStart":5439,"sourceCodeEnd":5475,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L5439-L5475","documentation":"During execution-verification state migration, the client replays each retained signed intent and requires a `current` transaction record (the current hash/attempt) to be present. This error is thrown when an active, signed intent has a nonce but its `current` option is None, meaning the persisted state is missing the hash of the transaction the signature was produced for. The library throws it because it cannot verify or migrate a signed intent without knowing which transaction hash it refers to, so it fails loudly instead of silently dropping on-chain state.","triggerScenarios":"Raised by the migration routine in `client.rs` (`ok_or_else` on `current.ok_or_else(...)`) when iterating retained intents where: intent.active is true, intent.nonce is Some, but the `current` transaction record for the intent is absent from the loaded persistence snapshot — e.g. a partially-written or hand-edited state store, a truncated write that stored the intent but not its current transaction row, or deserializing state saved by a version that did not persist the current hash.","commonSituations":"Crash or kill between persisting the intent and its transaction hash; restoring state from an old backup or downgraded node against a newer state schema; manual tampering with the execution state DB; copying intent rows without their joined transaction rows between environments.","solutions":["Inspect the persisted execution state for the intent id reported in the message and restore the missing current transaction record from a complete backup.","Re-run state persistence from a consistent snapshot: stop the node, restore the latest intact state file/DB, and restart so migration sees the full intent+transaction pair.","If the intent was never broadcast and its signature is unusable, remove or mark the intent as `recoverable`/`dropped` in the state store (which the migration path allows for nonterminal intents) before restarting.","Check that you are not mixing state produced by different adapter versions; upgrade/downgrade consistently so the `current` hash field is always populated."],"exampleFix":"// before (corrupt state row: intent persisted without current transaction)\n{\"id\": \"intent-42\", \"active\": true, \"nonce\": 7}  // no current hash\n\n// after (complete record restored from backup)\n{\"id\": \"intent-42\", \"active\": true, \"nonce\": 7, \"current\": {\"id\": \"tx-9\", \"transaction_hash\": \"0xabc...\"}}","handlingStrategy":"validation","validationCode":"fn validate_signed_intent(intent: &Intent, current: Option<&TxRecord>) -> Result<(), String> {\n    if intent.active && intent.nonce.is_some() && current.is_none() {\n        return Err(format!(\"intent {} is signed but missing current hash\", intent.id));\n    }\n    Ok(())\n}","typeGuard":"fn has_current(intent: &Intent) -> bool {\n    intent.active && intent.nonce.is_some() && intent.current.is_some()\n}","tryCatchPattern":null,"preventionTips":["Write intent records and their current-transaction rows atomically in one store transaction.","Never hand-edit or partially copy the execution state store between environments.","Back up state only at quiescent points (no in-flight intents).","Version-check state schema before loading state saved by a different adapter release."],"tags":["blockchain","state-migration","missing-data","persistence"],"backgroundTag":"record-not-found","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"}