{"record":{"id":"7383cc7fdc500957","repo":"nautechsystems/nautilus_trader","slug":"websocket-output-receiver-not-available","errorCode":null,"errorMessage":"WebSocket output receiver not available","messagePattern":"WebSocket output receiver not available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/coinbase/src/data/mod.rs","lineNumber":265,"sourceCode":"            self.ws_client.update_instrument(instrument.clone()).await;\n        }\n\n        log::debug!(\"Bootstrapped {} instruments\", instruments.len());\n        Ok(instruments)\n    }\n\n    async fn spawn_ws(&mut self) -> anyhow::Result<()> {\n        self.ws_client\n            .connect()\n            .await\n            .context(\"failed to connect to Coinbase WebSocket\")?;\n\n        let Some(mut out_rx) = self.ws_client.take_out_rx() else {\n            self.ws_client\n                .disconnect()\n                .await\n                .context(\"failed to roll back Coinbase WebSocket without output receiver\")?;\n            anyhow::bail!(\"WebSocket output receiver not available\");\n        };\n\n        let data_sender = self.data_sender.clone();\n        let cancellation_token = self.cancellation_token.clone();\n        let status_subs = Arc::clone(&self.instrument_status_subs);\n\n        let future = async move {\n            log::debug!(\"Coinbase WebSocket consumption loop started\");\n\n            loop {\n                tokio::select! {\n                    () = cancellation_token.cancelled() => {\n                        log::debug!(\"WebSocket consumption loop cancelled\");\n                        break;\n                    }\n                    msg_opt = out_rx.recv() => {\n                        match msg_opt {\n                            Some(msg) => dispatch_ws_message(msg, &data_sender, &status_subs),","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/coinbase/src/data/mod.rs#L247-L283","documentation":"During CoinbaseDataAdapter startup, spawn_ws consumes the WebSocket client's output receiver channel exactly once (take_out_rx). If the receiver is already taken or was never created, the adapter rolls back the just-established WebSocket connection and aborts the connect flow. This is an internal lifecycle guard against a double-consumed WS stream.","triggerScenarios":"Calling connect (via spawn_ws) twice without recreating the adapter's WebSocket client, or constructing the adapter with a ws_client whose output channel was already consumed by another spawn_ws call.","commonSituations":"Reconnect logic that reuses a stale adapter/WS client after a previous connect; spawning two data tasks sharing one adapter; tests or scripts that call connect() repeatedly on the same instance.","solutions":["Create a fresh adapter/WS client for each connect() call instead of reconnecting on a used instance","Ensure only one consumer calls take_out_rx; do not share the ws_client across concurrent connect paths","Check that any prior connect attempt fully tore down (disconnect) before reconnecting, and recreate channels","Inspect logs for the 'failed to roll back Coinbase WebSocket' context to confirm the rollback succeeded"],"exampleFix":"// before\nlet mut adapter = CoinbaseDataClientFactory::create(...);\nadapter.connect().await?;\nadapter.disconnect().await?;\nadapter.connect().await?; // receiver already taken\n\n// after\nlet mut adapter = CoinbaseDataClientFactory::create(...);\nadapter.connect().await?;\nadapter.disconnect().await?;\nlet mut adapter = CoinbaseDataClientFactory::create(...); // fresh client/channel\nadapter.connect().await?;","handlingStrategy":"try-catch","validationCode":"// before connect: ensure a fresh client\nassert!(!adapter.is_connected(), \"adapter already connected; recreate it\");","typeGuard":null,"tryCatchPattern":"match adapter.connect().await {\n    Err(e) if e.to_string().contains(\"output receiver not available\") => {\n        // recreate the adapter/WS client and retry once\n    }\n    other => other?,\n}","preventionTips":["Treat connect() as one-shot: construct a new client per connection cycle","Never share one Coinbase ws_client across two consumers","Always disconnect() and rebuild before reconnecting","Watch for double-spawn of the data task in reconnect loops"],"tags":["websocket","lifecycle","rust","connection"],"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-14T00:17:10.932Z"}