nautechsystems/nautilus_trader · error · anyhow::Error
Failed to send unsubscribe command: {e}
Error message
Failed to send unsubscribe command: {e} What it means
This error is returned by send_unsubscription when the Unsubscribe HandlerCommand cannot be sent to the handler task over the command channel. The channel being closed means the handler task that processes unsubscriptions has terminated.
Source
Thrown at crates/adapters/hyperliquid/src/websocket/client.rs:2124
}) {
if reserved {
self.rate_limits.release_subscription(self.client_id, &key);
}
anyhow::bail!("Failed to send subscribe command: {e}");
}
Ok(())
}
fn send_unsubscription(
&self,
cmd_tx: &tokio::sync::mpsc::UnboundedSender<HandlerCommand>,
subscription: SubscriptionRequest,
) -> anyhow::Result<()> {
cmd_tx
.send(HandlerCommand::Unsubscribe {
subscriptions: vec![subscription],
})
.map_err(|e| anyhow::anyhow!("Failed to send unsubscribe command: {e}"))
}
/// Receives the next message from the WebSocket handler.
///
/// Returns `None` if the handler has disconnected or the receiver was already taken.
pub async fn next_event(&mut self) -> Option<NautilusWsMessage> {
if let Some(ref mut rx) = self.out_rx {
rx.recv().await
} else {
None
}
}
fn release_limit_reservations(&self) {
self.rate_limits.release_client(self.client_id);
self.connection_permit.lock().take();
}
}View on GitHub (pinned to 18893faf8b)
Solutions
- Guard unsubscribe calls with a connection-alive check
- If disconnected, drop local state instead of sending the command
- Reconnect/recreate the client before further use
- Check logs for a prior handler task panic
Example fix
// before
client.unsubscribe(data_type).await?;
// after
if client.is_connected() {
client.unsubscribe(data_type).await?;
} else {
log::warn!("skipping unsubscribe, handler disconnected");
} Defensive patterns
Strategy: try-catch
Validate before calling
// Rust
fn should_unsubscribe(client: &HyperliquidWsClient) -> bool {
client.is_connected()
} Try / catch
if client.is_connected() {
client.unsubscribe(sub).await?;
} else {
log::debug!("handler disconnected; skipping unsubscribe");
} Prevention
- Guard cleanup paths with connection checks
- Handle shutdown ordering: unsubscribe before close()
- Ignore send-to-closed-channel errors during teardown
- Recreate clients after teardown instead of reuse
When it happens
Trigger: Any call to unsubscribe(...) after the handler task has dropped its receiver — e.g. after a disconnect, handler panic, or client close while an unsubscribe is still pending.
Common situations: Application shutdown where cleanup calls unsubscribe after the connection already closed; a crashed handler task; using a client handle from a previous connection session.
Related errors
- Failed to send subscribe command: {e}
- Failed to send SetDepth10Sub command: {e}
- Failed to send UpdateTradeSubs command: {e}
- Failed to send AddBarType command: {e}
- Failed to send resubscribe command: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d4bd7d5355c4b8d4.
Report an issue: GitHub.