{"record":{"id":"32115d5460dbed23","repo":"nautechsystems/nautilus_trader","slug":"persisted-swap-strategy-does-not-match-restored-or","errorCode":null,"errorMessage":"Persisted swap strategy does not match restored order","messagePattern":"Persisted swap strategy does not match restored order","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":1053,"sourceCode":"                    intent.id\n                )\n            })?;\n        let instrument_id = InstrumentId::from_str(\n            intent\n                .instrument_id\n                .as_deref()\n                .ok_or_else(|| anyhow::anyhow!(\"Persisted swap intent has no instrument ID\"))?,\n        )?;\n        anyhow::ensure!(\n            order.instrument_id() == instrument_id,\n            \"Persisted swap instrument {instrument_id} does not match restored order instrument {}\",\n            order.instrument_id()\n        );\n        anyhow::ensure!(\n            intent.trader_id.as_deref() == Some(order.trader_id().as_str()),\n            \"Persisted swap trader does not match restored order\"\n        );\n        anyhow::ensure!(\n            intent.strategy_id.as_deref() == Some(order.strategy_id().as_str()),\n            \"Persisted swap strategy does not match restored order\"\n        );\n        anyhow::ensure!(\n            intent.account_id.as_deref() == Some(self.core.account_id.as_str()),\n            \"Persisted swap account does not match execution client account\"\n        );\n\n        let pool = self.resolve_pool(&instrument_id)?;\n        let pool_address = Address::from_str(\n            intent\n                .pool_address\n                .as_deref()\n                .ok_or_else(|| anyhow::anyhow!(\"Persisted swap intent has no pool address\"))?,\n        )?;\n        anyhow::ensure!(\n            pool.address == pool_address,\n            \"Persisted pool {pool_address} does not match restored pool {}\",","sourceCodeStart":1035,"sourceCodeEnd":1071,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L1035-L1071","documentation":"restore_swap_plan checks that the strategy_id persisted on the execution intent row equals the strategy_id of the restored order. A mismatch means the durable swap intent and the cached order belong to different trading strategies, so the client refuses to rebuild the SwapPlan. This prevents a persisted swap from being attributed to, or executed on behalf of, the wrong strategy.","triggerScenarios":"reconcile_unresolved_execution (from connect) or build_execution_verification_migration finds an active ExecutionIntentRow whose intent.strategy_id is None or differs from order.strategy_id() of the restored order. Occurs when strategy IDs were renamed/reassigned between runs, or orders were restored from a snapshot with different strategy assignments.","commonSituations":"Renaming a StrategyId in the trading config while a swap intent is still pending in the durable store; reassigning instruments/orders to a different strategy; sharing one database across deployments with different strategy layouts; old persisted rows predating strategy-id tracking (NULL column).","solutions":["Restore the original strategy_id configuration so the restored order's strategy matches the persisted intent.","Let the pending swap resolve before changing strategy assignments/renames, or manually finalize/cancel the intent in the durable store.","Use a per-strategy (or per-deployment) durable store so intents are not mixed across strategy layouts.","If the row is genuinely stale/corrupt, mark or delete the active intent so reconciliation can proceed."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if intent.strategy_id.as_deref() != Some(order.strategy_id().as_str()) {\n    eprintln!(\"strategy mismatch between persisted intent and restored order; resolve pending swaps before renaming strategies\");\n}","typeGuard":"fn strategy_matches(intent: &ExecutionIntentRow, order: &OrderAny) -> bool {\n    intent.strategy_id.as_deref() == Some(order.strategy_id().as_str())\n}","tryCatchPattern":null,"preventionTips":["Avoid renaming StrategyId while swaps are pending in the durable store","Scope durable stores per strategy or per deployment","Restore orders from the same snapshot that produced the intents","Check for NULL strategy_id on legacy rows before reconnecting"],"tags":["persistence","reconciliation","strategy-id","identity-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}