{"record":{"id":"d883ebf34b565fd0","repo":"nautechsystems/nautilus_trader","slug":"failed-to-start-websocket-handler-task-generation","errorCode":null,"errorMessage":"failed to start WebSocket handler task generation: {e}","messagePattern":"failed to start WebSocket handler task generation: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/deribit/src/websocket/client.rs","lineNumber":537,"sourceCode":"    /// Returns an error if the connection 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        log_debug!(\n            \"Connecting to WebSocket: {}\",\n            self.url,\n            color = LogColor::Blue\n        );\n\n        if !self.handler_tasks.is_open() || !self.handler_tasks.is_empty() {\n            self.handler_tasks.begin_shutdown();\n            self.signal.store(true, Ordering::Relaxed);\n            self.finish_handler()\n                .await\n                .map_err(|e| anyhow::anyhow!(\"failed to stop prior WebSocket handler: {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\n        // Reset stop signal and subscription state so callers can\n        // resubscribe cleanly after a manual disconnect/connect cycle.\n        self.signal.store(false, Ordering::Relaxed);\n        self.subscriptions_state.clear();\n\n        // Create message handler and channel\n        let (message_handler, raw_rx) = channel_message_handler();\n\n        // No-op ping handler: handler responds to pings directly\n        // Inbound Ping frames are answered by the transport, so no ping handler is needed;\n        // the reader routes them away from the message channel and the handler never sees them.\n","sourceCodeStart":519,"sourceCodeEnd":555,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/deribit/src/websocket/client.rs#L519-L555","documentation":"After stopping prior handler tasks during `connect()`, the client advances `handler_tasks` to a new generation via `start_generation()`. This error wraps a failure of that generation rollover, meaning the client cannot prepare a fresh task-generation for the new WebSocket session.","triggerScenarios":"Calling `connect()` after prior handlers exist and `handler_tasks.start_generation()` returns an Err — e.g. the generation manager still considers a prior generation active, or it was shut down and cannot restart.","commonSituations":"Rapid disconnect/reconnect cycles racing the previous generation's teardown; a prior `finish_handler()` that only partially completed; shutting down the task group while a reconnect is in flight.","solutions":["Inspect the wrapped `{e}` from start_generation for the specific generation-state reason.","Wait for full teardown of the previous session (await disconnect) before reconnecting.","Serialize connect calls; add a mutex/actor around connect/disconnect.","If the task group was permanently shut down, rebuild a new client instance instead of reconnecting.","File/inspect TaskGroup logic if start_generation fails on a fresh open group."],"exampleFix":"// before\nclient.connect().await?; // may race old generation teardown\n// after\ntokio::time::sleep(Duration::from_millis(100)).await; // or await disconnect completion\nclient.connect().await?;","handlingStrategy":"try-catch","validationCode":"// Track session lifecycle yourself; only connect when fully disconnected.\nassert!(client.is_disconnected());","typeGuard":null,"tryCatchPattern":"if let Err(e) = client.connect().await {\n    if e.to_string().contains(\"handler task generation\") {\n        tokio::time::sleep(RECONNECT_DELAY).await;\n        client = rebuild_client().await?;\n    }\n}","preventionTips":["Await previous disconnect completion before connect.","Use bounded retry with backoff on reconnect loops.","Avoid sharing one client across concurrent tasks without a mutex.","Recreate the client after repeated generation errors."],"tags":["websocket","task-generation","connection-lifecycle"],"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"}