{"record":{"id":"5f48baba17146a5d","repo":"nautechsystems/nautilus_trader","slug":"failed-to-start-coinbase-websocket-handler-task","errorCode":null,"errorMessage":"Failed to start Coinbase WebSocket handler task: {e}","messagePattern":"Failed to start Coinbase WebSocket handler task: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/coinbase/src/websocket/client.rs","lineNumber":377,"sourceCode":"                            log::debug!(\"Output channel closed: {e}\");\n                            break;\n                        }\n                    }\n                    Some(msg) => {\n                        if let Err(e) = out_tx.send(msg) {\n                            log::debug!(\"Output channel closed: {e}\");\n                            break;\n                        }\n                    }\n                    None => {\n                        log::debug!(\"Feed handler stopped\");\n                        break;\n                    }\n                }\n            }\n        }) {\n            self.out_rx = None;\n            anyhow::bail!(\"Failed to start Coinbase WebSocket handler task: {e}\");\n        }\n\n        Ok(())\n    }\n\n    /// Subscribes to a channel for the given product IDs.\n    pub async fn subscribe(\n        &self,\n        channel: CoinbaseWsChannel,\n        product_ids: &[Ustr],\n    ) -> anyhow::Result<()> {\n        let jwt = if channel.requires_auth() {\n            let credential = self\n                .credential\n                .as_ref()\n                .ok_or_else(|| anyhow::anyhow!(\"Credentials required for {channel}\"))?;\n            Some(credential.build_ws_jwt()?)\n        } else {","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/coinbase/src/websocket/client.rs#L359-L395","documentation":"connect() spawns the long-running WebSocket handler task with tokio::spawn; if the spawn call itself returns Err (the runtime cannot start the task), the adapter rolls back out_rx and returns this error.","triggerScenarios":"tokio::spawn fails — practically only when there is no active Tokio runtime context or the runtime is shutting down while connect() is invoked.","commonSituations":"Calling connect() outside an async runtime (blocking context without a runtime handle); application shutdown tearing down the runtime while the adapter reconnects; blocking the runtime so shutdown aborts spawn.","solutions":["Ensure connect() is awaited inside a live tokio runtime (e.g. #[tokio::main] or a Handle)","Delay adapter shutdown until WebSocket disconnect() finishes","If spawning from a plain thread, obtain a tokio::runtime::Handle and use handle.spawn"],"exampleFix":"// before\nstd::thread::spawn(|| ws.connect().await); // no runtime\n// after\nlet handle = tokio::runtime::Handle::current();\nhandle.spawn(async move { ws.connect().await });","handlingStrategy":"try-catch","validationCode":"// ensure a runtime exists before constructing/connecting the client\nlet handle = tokio::runtime::Handle::try_current()\n    .map_err(|_| \"Coinbase WebSocket requires a tokio runtime\")?;","typeGuard":null,"tryCatchPattern":"match tokio::runtime::Handle::try_current() {\n    Ok(h) => { /* safe to call connect().await within runtime */ }\n    Err(_) => { /* build/enter a runtime or use handle.spawn */ }\n}","preventionTips":["Only use async adapter APIs inside a Tokio runtime","Complete adapter shutdown before runtime teardown","Use runtime Handle::spawn for cross-thread usage"],"tags":["rust","tokio","websocket","runtime"],"backgroundTag":"task-spawn-failed","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"}