{"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":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":849,"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":831,"sourceCodeEnd":867,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/2114cf6f761429e0adb5ca9596fcd7b895b16011/crates/adapters/blockchain/src/execution/client.rs#L831-L867","documentation":"restore_swap_plan (crates/adapters/blockchain/src/execution/client.rs:849) requires the persisted intent's strategy_id to match the strategy of the restored order named by its client order id. A mismatch means the durable swap record was spawned by a different strategy than the live order - reconciliation aborts so fills are never attributed to the wrong strategy. Strategy attribution flows into every emitted order event, hence the strict equality check.","triggerScenarios":"Strategy configuration changed across restarts while an intent persisted by the old strategy is still active; the order cache restored under a different strategy id; a client order id reused by a different strategy in a later session.","commonSituations":"Renaming strategies in config between runs; promoting a strategy id from paper to live trading with stale intents in the store.","solutions":["Compare the intent's strategy_id with the current strategy configuration and the restored order's strategy.","Verify the on-chain outcome of the intent's transaction and mark the intent resolved to unblock reconciliation.","Clear active intents before changing strategy identifiers.","Keep strategy ids stable for the lifetime of any intent they create."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"-- Pre-flight: intents recorded under a strategy other than current config\nSELECT id, strategy_id, status\nFROM execution_intent\nWHERE status IN ('prepared', 'signed', 'submitted');","typeGuard":"fn is_strategy_mismatch(e: &anyhow::Error) -> bool {\n    e.to_string().contains(\"Persisted swap strategy does not match restored order\")\n}","tryCatchPattern":"if let Err(e) = client.connect().await {\n    if is_strategy_mismatch(&e) {\n        // strategy attribution conflict: resolve the stale intent before trading\n        log::error!(\"swap intent belongs to a different strategy: {e}\");\n    }\n    return Err(e);\n}","preventionTips":["Do not rename strategies while intents from the old strategy are active.","Clear or complete active intents before reassigning strategy ids.","Keep strategy_id stable for the lifetime of any intent it creates."],"tags":["reconciliation","strategy-id","state-mismatch","configuration","rust"],"backgroundTag":"persisted-state-mismatch","analyzedSha":"2114cf6f761429e0adb5ca9596fcd7b895b16011","analyzedAt":"2026-08-21T11:28:30.864Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}