{"record":{"id":"a25b749bd12c3eb7","repo":"nautechsystems/nautilus_trader","slug":"failed-to-send-unsubscribe-command-e","errorCode":null,"errorMessage":"Failed to send Unsubscribe command: {e}","messagePattern":"Failed to send Unsubscribe command: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/coinbase/src/websocket/client.rs","lineNumber":460,"sourceCode":"        let channel_str = channel.as_ref();\n\n        if product_ids.is_empty() {\n            self.subscriptions.mark_unsubscribe(channel_str);\n        } else {\n            for product_id in product_ids {\n                let topic = format!(\"{channel_str}|{product_id}\");\n                self.subscriptions.mark_unsubscribe(&topic);\n            }\n        }\n\n        let cmd_tx = self.cmd_tx.read().await;\n        cmd_tx\n            .send(HandlerCommand::Unsubscribe {\n                channel: unsub.channel,\n                product_ids: unsub.product_ids,\n                payload: unsub.payload,\n            })\n            .map_err(|e| anyhow::anyhow!(\"Failed to send Unsubscribe command: {e}\"))\n    }\n\n    /// Returns the next parsed message from the feed handler.\n    pub async fn next_message(&mut self) -> Option<NautilusWsMessage> {\n        self.out_rx.as_mut()?.recv().await\n    }\n\n    /// Disconnects the WebSocket and stops the feed handler.\n    pub(crate) fn begin_shutdown(&self) {\n        self.signal.store(true, Ordering::Release);\n    }\n\n    /// Disconnects the WebSocket and stops the feed handler.\n    pub async fn disconnect(&mut self) -> anyhow::Result<()> {\n        // Send Disconnect command before setting the signal so the handler\n        // processes it and calls notify_closed() on the inner WebSocket client\n        let cmd_tx = self.cmd_tx.read().await;\n","sourceCodeStart":442,"sourceCodeEnd":478,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/coinbase/src/websocket/client.rs#L442-L478","documentation":"`unsubscribe` sends an Unsubscribe command to the handler task over the mpsc command channel; failure means the receiver no longer exists, i.e. the handler task has terminated. The SendError is wrapped with this message.","triggerScenarios":"Calling `unsubscribe` after the websocket handler task has exited (client closed, connection terminated, or task crashed), so `cmd_tx.send(HandlerCommand::Unsubscribe)` fails.","commonSituations":"Tearing down subscriptions during shutdown after the client was already closed; unsubscribe racing with a fatal disconnect.","solutions":["Verify the client is still connected/running before unsubscribing","If the handler is gone, the subscriptions are already gone — treat this as a no-op rather than an unrecoverable fault","Reconnect the client before attempting further subscribe/unsubscribe calls","Ensure close() is not called before pending unsubscribe calls complete"],"exampleFix":"// before\nclient.unsubscribe(channel, &products).await?;\n// after\nif let Err(e) = client.unsubscribe(channel, &products).await {\n    log::debug!(\"unsubscribe skipped, client closed: {e}\");\n}","handlingStrategy":"try-catch","validationCode":"async fn safe_unsubscribe(client: &CoinbaseWsClient, channel: CoinbaseWsChannel, products: &[Ustr]) {\n    if client.is_closed() { return; } // subscriptions are already gone\n    let _ = client.unsubscribe(channel, products).await;\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = client.unsubscribe(channel, &products).await {\n    log::debug!(\"unsubscribe ignored (handler gone): {e}\");\n}","preventionTips":["Skip unsubscribe on already-closed clients","Don't interleave unsubscribe calls with client shutdown","Treat unsubscribe failure during teardown as informational, not fatal"],"tags":["coinbase","websocket","channel","lifecycle"],"backgroundTag":"broken-pipe","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"}