{"record":{"id":"4f88a90550c92e22","repo":"nautechsystems/nautilus_trader","slug":"failed-to-disconnect-execution-clients","errorCode":null,"errorMessage":"Failed to disconnect execution clients: {}","messagePattern":"Failed to disconnect execution clients: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/execution/src/engine/mod.rs","lineNumber":669,"sourceCode":"    ///\n    /// # Errors\n    ///\n    /// Returns an error if any client fails to disconnect.\n    pub async fn disconnect(&mut self) -> anyhow::Result<()> {\n        let futures: Vec<_> = self\n            .get_clients_mut()\n            .into_iter()\n            .map(ExecutionClientAdapter::disconnect)\n            .collect();\n\n        let results = join_all(futures).await;\n        let errors: Vec<_> = results.into_iter().filter_map(Result::err).collect();\n\n        if errors.is_empty() {\n            Ok(())\n        } else {\n            let error_msgs: Vec<_> = errors.iter().map(ToString::to_string).collect();\n            anyhow::bail!(\n                \"Failed to disconnect execution clients: {}\",\n                error_msgs.join(\"; \")\n            )\n        }\n    }\n\n    /// Sets the `manage_own_order_books` configuration option.\n    pub fn set_manage_own_order_books(&mut self, value: bool) {\n        self.config.manage_own_order_books = value;\n    }\n\n    /// Starts the position snapshot timer if configured.\n    #[expect(\n        clippy::missing_panics_doc,\n        reason = \"timer registration is not expected to fail\"\n    )]\n    pub fn start_snapshot_timer(&mut self) {\n        if let Some(interval_secs) = self","sourceCodeStart":651,"sourceCodeEnd":687,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/execution/src/engine/mod.rs#L651-L687","documentation":"The engine's disconnect() calls disconnect on all registered execution clients concurrently and aggregates individual failures. If any client fails to disconnect, it bails with this error containing all per-client error messages joined by '; '.","triggerScenarios":"Calling ExecutionEngine::disconnect() when one or more execution clients' disconnect() implementations return Err — e.g. network failures while closing exchange connections, or adapter-specific cleanup errors.","commonSituations":"Shutting down a node while a venue connection is already broken or the WebSocket close handshake times out; a fault-injected or stale adapter failing cleanup; live client to an unreachable exchange during shutdown.","solutions":["Read the joined per-client messages in the error to identify which clients failed and why.","For transient network causes, retry disconnect() — it is safe to call during shutdown as long as clients are still registered.","Fix the underlying client disconnect implementation if the failure is deterministic (adapter bug).","If shutdown must proceed regardless, tolerate/log this error: failing to disconnect at process exit typically doesn't require aborting the shutdown.","Ensure clients are connected before disconnecting; check connection state handling in the adapter."],"exampleFix":"// before\nengine.disconnect().await?; // aborts shutdown on one bad client\n// after\nif let Err(e) = engine.disconnect().await {\n    log::warn!(\"disconnect failures during shutdown: {e}\");\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match engine.disconnect().await {\n    Err(e) if e.to_string().starts_with(\"Failed to disconnect execution clients\") => {\n        log::warn!(\"non-fatal disconnect failures: {e}\"); // proceed with shutdown\n    }\n    other => other?,\n}","preventionTips":["Ensure clients are connected and healthy before shutdown-time disconnect.","Inspect the joined per-client messages to find the failing adapter.","During process exit, log rather than propagate disconnect aggregation errors.","Implement robust disconnect in custom ExecutionClient adapters (handle already-closed connections)."],"tags":["execution-engine","disconnect","network","aggregated-errors","rust"],"backgroundTag":"connection-refused","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}