{"record":{"id":"c7537fab46fb88a5","repo":"nautechsystems/nautilus_trader","slug":"retained-execution-history-has-multiple-active-sig","errorCode":null,"errorMessage":"Retained execution history has multiple active signer owners","messagePattern":"Retained execution history has multiple active signer owners","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":5323,"sourceCode":"        snapshot: ExecutionVerificationMigrationSnapshot,\n        finalized: VerifiedBlockHeader,\n        finalized_headers: &[VerifiedBlockHeader],\n        nonce_verification: &Verified<u64>,\n    ) -> anyhow::Result<ExecutionVerificationMigration> {\n        let next_canonical_nonce = nonce_verification.value;\n        let mut hashes_by_intent: HashMap<i64, Vec<&ExecutionTransactionHashRow>> = HashMap::new();\n        for hash in &snapshot.hashes {\n            hashes_by_intent\n                .entry(hash.intent_id)\n                .or_default()\n                .push(hash);\n        }\n        let active_count = snapshot\n            .intents\n            .iter()\n            .filter(|intent| intent.active)\n            .count();\n        anyhow::ensure!(\n            active_count <= 1,\n            \"Retained execution history has multiple active signer owners\"\n        );\n\n        let mut nonce_owners = HashMap::new();\n        let mut records = Vec::with_capacity(snapshot.intents.len());\n        let finalized_headers = finalized_headers\n            .iter()\n            .map(durable_verified_header)\n            .collect::<Vec<_>>();\n\n        for intent in &snapshot.intents {\n            anyhow::ensure!(\n                intent.chain_id == self.chain.chain_id\n                    && intent.wallet_address == self.config.wallet_address,\n                \"Retained execution intent belongs to another signer\"\n            );\n            let purpose = TransactionPurpose::parse(&intent.purpose).ok_or_else(|| {","sourceCodeStart":5305,"sourceCodeEnd":5341,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L5305-L5341","documentation":"During recovery of durable execution state (the retained snapshot of signer intents), the client requires at most one intent to be marked active, since a signer can only have one in-flight transaction. Multiple active intents mean the persisted history is corrupt or was produced by concurrent writers, so recovery is refused rather than guessing which intent is live.","triggerScenarios":"Loading a retained execution snapshot at client startup where snapshot.intents contains two or more entries with active == true.","commonSituations":"Two client instances sharing the same durable storage/wallet concurrently marking intents active; a crash between deactivating an old intent and activating a new one combined with a non-atomic writer; manually edited or partially migrated state files.","solutions":["Stop all clients sharing the wallet/storage, inspect the snapshot, and deactivate stale intents so at most one remains active","Delete or archive the corrupted snapshot to force a clean rebuild of execution history (verify no transaction is actually in flight on-chain first)","Ensure only one process per wallet writes to the durable store, and make activate/deactivate transitions atomic"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"fn snapshot_recoverable(snapshot: &ExecutionSnapshot) -> Result<(), String> {\n    let active = snapshot.intents.iter().filter(|i| i.active).count();\n    if active > 1 { Err(format!(\"{active} active intents in snapshot\".into())) } else { Ok(()) }\n}","typeGuard":null,"tryCatchPattern":"match client.start_with_snapshot(snapshot) {\n    Err(e) if e.to_string().contains(\"multiple active signer owners\") => {\n        // halt writers, reconcile snapshot on-chain, rebuild state before retry\n    }\n    other => other?,\n}","preventionTips":["Run exactly one client instance per wallet/durable store","Make active-intent transitions atomic (single write transaction)","Back up snapshots before recovery and inspect on-chain state before clearing"],"tags":["state-corruption","recovery","signer","invariant-violation","durable-state"],"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-14T05:17:10.506Z"}