{"record":{"id":"7cb7a556f6ca37c0","repo":"nautechsystems/nautilus_trader","slug":"failed-to-send-subscribe-command-e","errorCode":null,"errorMessage":"Failed to send subscribe command: {e}","messagePattern":"Failed to send subscribe command: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/hyperliquid/src/websocket/client.rs","lineNumber":2110,"sourceCode":"\n    fn send_subscription(\n        &self,\n        cmd_tx: &tokio::sync::mpsc::UnboundedSender<HandlerCommand>,\n        subscription: SubscriptionRequest,\n    ) -> anyhow::Result<()> {\n        let key = crate::websocket::handler::subscription_to_key(&subscription);\n        let reserved = self\n            .rate_limits\n            .reserve_subscription(self.client_id, &subscription)\n            .map_err(anyhow::Error::msg)?;\n\n        if let Err(e) = cmd_tx.send(HandlerCommand::Subscribe {\n            subscriptions: vec![subscription],\n        }) {\n            if reserved {\n                self.rate_limits.release_subscription(self.client_id, &key);\n            }\n            anyhow::bail!(\"Failed to send subscribe command: {e}\");\n        }\n        Ok(())\n    }\n\n    fn send_unsubscription(\n        &self,\n        cmd_tx: &tokio::sync::mpsc::UnboundedSender<HandlerCommand>,\n        subscription: SubscriptionRequest,\n    ) -> anyhow::Result<()> {\n        cmd_tx\n            .send(HandlerCommand::Unsubscribe {\n                subscriptions: vec![subscription],\n            })\n            .map_err(|e| anyhow::anyhow!(\"Failed to send unsubscribe command: {e}\"))\n    }\n\n    /// Receives the next message from the WebSocket handler.\n    ///","sourceCodeStart":2092,"sourceCodeEnd":2128,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/hyperliquid/src/websocket/client.rs#L2092-L2128","documentation":"This error is raised when the WebSocket client fails to enqueue a Subscribe command onto the channel consumed by the connection's message-handler task (cmd_tx.send returns an error, which in Rust means the receiving task has been dropped, i.e. the handler/connection is shut down). The subscription is then aborted; if a rate-limit slot was reserved for the subscription it is released back before failing. It is a wrapping of an internal send failure, so the root cause is that the handler task is no longer running.","triggerScenarios":"Calling a subscribe method (e.g. to subscribe to trades/l2Book/candle channels) when the underlying WebSocket handler task has already terminated or is being shut down. Any API path that builds a subscription and sends HandlerCommand::Subscribe through cmd_tx will produce this if the receiver was dropped.","commonSituations":"Subscribing after the connection dropped or was closed; racing a subscribe call with client shutdown/disconnect; a crashed or aborted handler task (network loss, server closed the socket, panic in handler) leaving the channel with no receiver; calling subscribe on a stale/cloned client handle after reconnect logic replaced the transport.","solutions":["Check connection state before subscribing and reconnect the WebSocket client first; then retry the subscription.","Wrap the subscribe call so the error is handled and the client is reconnected (call connect/reconnect), then re-issue the subscription.","Avoid subscribing concurrently with shutdown: ensure the handler task is alive (guard with a ConnectionClosed/disconnected check or hold the client alive).","Enable tracing logs to find why the handler task exited (network error, server close) and fix that root cause."],"exampleFix":"// before\nclient.subscribe(subscription).await?;\n// after\nif client.is_connected() {\n    if let Err(e) = client.subscribe(subscription).await {\n        tracing::warn!(\"subscribe failed ({e}); reconnecting\");\n        client.connect().await?;\n        client.subscribe(subscription).await?;\n    }\n}","handlingStrategy":"try-catch","validationCode":"// before subscribing\nif !ws_client.is_connected() {\n    ws_client.connect().await?;\n}","typeGuard":"fn can_subscribe(client: &HyperliquidWsClient) -> bool {\n    client.is_connected()\n}","tryCatchPattern":"match client.subscribe(subscription).await {\n    Ok(()) => {}\n    Err(e) if e.to_string().contains(\"Failed to send subscribe command\") => {\n        // handler task gone: reconnect then re-subscribe\n        client.connect().await?;\n        client.subscribe(subscription).await?;\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Check connection state before every subscribe call","Re-issue subscriptions after every reconnect","Avoid firing subscribe calls concurrently with client shutdown","Keep a single owned client handle rather than stale clones after reconnects"],"tags":["websocket","rust","hyperliquid","channel-closed","subscribe"],"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"}