{"record":{"id":"a131dd89c1e177ec","repo":"nautechsystems/nautilus_trader","slug":"failed-to-start-websocket-handler-task-generation-a131dd","errorCode":null,"errorMessage":"Failed to start WebSocket handler task generation: {e}","messagePattern":"Failed to start WebSocket handler task generation: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/websocket/client.rs","lineNumber":610,"sourceCode":"    /// # Errors\n    ///\n    /// Returns an error if the connection process fails.\n    pub async fn connect(&mut self) -> anyhow::Result<()> {\n        let connect_lock = Arc::clone(&self.connect_lock);\n        let _connect_guard = connect_lock.lock().await;\n\n        if !self.handler_tasks.is_empty() && !self.handler_tasks.all_finished() {\n            anyhow::bail!(\"Cannot connect while previous WebSocket handler task is still running\");\n        }\n\n        if !self.handler_tasks.is_open() || !self.handler_tasks.is_empty() {\n            self.handler_tasks.begin_shutdown();\n            self.handler_tasks\n                .finish_shutdown(Duration::from_secs(2), Duration::from_secs(2))\n                .await\n                .map_err(|e| anyhow::anyhow!(\"Previous WebSocket handler failed: {e}\"))?;\n            self.handler_tasks.start_generation().map_err(|e| {\n                anyhow::anyhow!(\"Failed to start WebSocket handler task generation: {e}\")\n            })?;\n        }\n        let handler_spawner = self.handler_tasks.spawner().map_err(|e| {\n            anyhow::anyhow!(\"Failed to acquire WebSocket handler task spawner: {e}\")\n        })?;\n        let handler_abort = CancellationToken::new();\n        *self.handler_abort.lock() = handler_abort.clone();\n        let mut rollback = ConnectRollback {\n            handler_tasks: Arc::clone(&self.handler_tasks),\n            signal: Arc::clone(&self.signal),\n            handler_abort: handler_abort.clone(),\n            socket_control: self.socket_control.clone(),\n            armed: true,\n        };\n\n        // Reset signal so is_active()/is_closed() work after a previous close()\n        self.signal.store(false, Ordering::Release);\n","sourceCodeStart":592,"sourceCodeEnd":628,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/websocket/client.rs#L592-L628","documentation":"After shutting down previous OKX WebSocket handler tasks, `connect` starts a new task generation in the handler task group. If `start_generation()` returns an error (task group in a bad state, e.g. still draining or already shutting down), connect aborts with this message.","triggerScenarios":"connect is called while the handler task group cannot begin a new generation — typically immediately after a failed shutdown of the prior generation or concurrent connect calls on the same client.","commonSituations":"Concurrent `connect()` calls from multiple threads/tasks sharing one client; reconnect logic racing with an in-progress disconnect; calling connect during client shutdown.","solutions":["Serialize connection lifecycle: guard connect/disconnect behind a mutex or ensure only one reconnect driver exists.","Retry connect after the previous shutdown completes (backoff and re-attempt).","Inspect the inner `{e}` to identify whether the task group is draining/shutdown and wait for that state to clear."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// rust\nfor attempt in 0..3 {\n    match client.connect().await {\n        Ok(()) => break,\n        Err(e) if e.to_string().contains(\"handler task generation\") => {\n            tokio::time::sleep(Duration::from_millis(500 * (attempt + 1))).await;\n        }\n        Err(e) => return Err(e),\n    }\n}","preventionTips":["Never share one client across concurrent connect calls.","Await disconnect completion before issuing a new connect.","Avoid connecting during client shutdown."],"tags":["websocket","okx","concurrency","task-group"],"backgroundTag":"invalid-state-transition","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"}