{"record":{"id":"18721d225c480b12","repo":"nautechsystems/nautilus_trader","slug":"persisted-swap-trader-does-not-match-restored-orde","errorCode":null,"errorMessage":"Persisted swap trader does not match restored order","messagePattern":"Persisted swap trader does not match restored order","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":845,"sourceCode":"            .try_order_owned(&client_order_id)\n            .with_context(|| {\n                format!(\n                    \"Cannot reconcile swap intent {} because order {client_order_id} is not restored\",\n                    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\"))?,","sourceCodeStart":827,"sourceCodeEnd":863,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/2114cf6f761429e0adb5ca9596fcd7b895b16011/crates/adapters/blockchain/src/execution/client.rs#L827-L863","documentation":"restore_swap_plan (crates/adapters/blockchain/src/execution/client.rs:845) verifies the persisted intent's trader_id equals the trader of the order restored under its client order id. A mismatch means the durable swap record belongs to a different trader than the live order - the client refuses to reconcile because completing it would attribute executions to the wrong account holder. The check guarantees trader attribution of emitted fills matches the persisted intent exactly.","triggerScenarios":"Trader configuration changed between the run that persisted the intent and the restarted run reconciling it; an order cache restored under a different trader_id while the old intent row remains active; intents written by a prior deployment under another trader account.","commonSituations":"Re-keying a deployment from a test trader to a production trader without clearing durable intents; multi-trader setups sharing one Postgres store.","solutions":["Check the intent row's trader_id versus the current trader configuration and the restored order's trader.","Resolve the orphaned intent on-chain (verify the transaction outcome) and mark it resolved so reconciliation no longer picks it up.","When changing trader configuration, drain or clear active intents first.","Scope intents per trader in the database to avoid cross-trader collisions."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"-- Pre-flight: intents recorded under a trader other than the one you will boot\nSELECT id, trader_id, status\nFROM execution_intent\nWHERE status IN ('prepared', 'signed', 'submitted');","typeGuard":"fn is_trader_mismatch(e: &anyhow::Error) -> bool {\n    e.to_string().contains(\"Persisted swap trader does not match restored order\")\n}","tryCatchPattern":"if let Err(e) = client.connect().await {\n    if is_trader_mismatch(&e) {\n        // attribution conflict: boot the trader that owns the intent, or resolve it first\n        log::error!(\"swap intent belongs to a different trader: {e}\");\n    }\n    return Err(e);\n}","preventionTips":["Drain active intents before changing trader configuration.","Give each trader its own durable store, or verify no foreign intents exist at boot.","Keep trader_id constant for the lifetime of any intent it creates."],"tags":["reconciliation","trader-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"}