nautechsystems/nautilus_trader · error · anyhow::Error
Failed to send UpdateAssetContextSubs command: {e}
Error message
Failed to send UpdateAssetContextSubs command: {e} What it means
This error is raised when the Hyperliquid WebSocket client cannot forward an UpdateAssetContextSubs HandlerCommand to its internal handler task over the command channel. It means the command mpsc channel is closed or the receiver was dropped, i.e. the handler task is no longer running. It is a wrapper around the underlying SendError, not a Hyperliquid exchange error.
Source
Thrown at crates/adapters/hyperliquid/src/websocket/client.rs:2003
instrument_id: InstrumentId,
data_type: AssetContextDataType,
) -> anyhow::Result<()> {
let instrument = self
.get_instrument(&instrument_id)
.ok_or_else(|| InstrumentLookupError::not_found(instrument_id))?;
let coin = instrument.raw_symbol().inner();
let mut entry = self.asset_context_subs.entry(coin).or_default();
let is_first_subscription = entry.is_empty();
entry.insert(data_type);
let data_types = entry.clone();
drop(entry);
let cmd_tx = self.cmd_tx.read().await;
cmd_tx
.send(HandlerCommand::UpdateAssetContextSubs { coin, data_types })
.map_err(|e| anyhow::anyhow!("Failed to send UpdateAssetContextSubs command: {e}"))?;
if is_first_subscription {
log::debug!(
"First asset context subscription for coin '{coin}', subscribing to ActiveAssetCtx"
);
let subscription = SubscriptionRequest::ActiveAssetCtx { coin };
cmd_tx
.send(HandlerCommand::UpdateInstrument(instrument.clone()))
.map_err(|e| anyhow::anyhow!("Failed to send UpdateInstrument command: {e}"))?;
if let Err(e) = self.send_subscription(&cmd_tx, subscription) {
if let Some(mut entry) = self.asset_context_subs.get_mut(&coin) {
entry.remove(&data_type);
let rollback = entry.clone();
let remove_entry = entry.is_empty();
drop(entry);
View on GitHub (pinned to 18893faf8b)
Solutions
- Reconnect the WebSocket client before subscribing; check connection state first
- Verify the client was connected and started before calling subscribe
- Treat this as a terminal client state: recreate the client instance
- Inspect logs for a prior handler-task panic that closed the command channel
Example fix
// before
client.subscribe(data_type).await?;
// after
if !client.is_connected() {
client.connect().await?;
}
client.subscribe(data_type).await?; Defensive patterns
Strategy: try-catch
Validate before calling
// Rust
fn can_subscribe(client: &HyperliquidWsClient) -> bool {
client.is_connected()
} Try / catch
match client.subscribe(data_type).await {
Ok(()) => {},
Err(e) if e.to_string().contains("Failed to send") => {
client.connect().await?;
client.subscribe(data_type).await?;
}
Err(e) => return Err(e),
} Prevention
- Always connect the client before subscribing
- Avoid calling subscribe after close()/drop of the client
- Monitor handler task health and reconnect on disconnect events
- Centralize subscribe calls behind a helper that checks connection state
When it happens
Trigger: Calling subscribe (or the asset-context subscription path) after the WebSocket handler task has terminated, e.g. after disconnect without reconnect, or calling before the client's handler task was ever started. cmd_tx.send returns Err and the anyhow wrapper adds this message.
Common situations: Reusing a client after connection teardown; a race where the handler task crashed (panic or network shutdown) while subscription logic still runs; calling subscribe concurrently with close(); keeping a stale client handle in long-lived services.
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/cd0ec8084ecb5f06.
Report an issue: GitHub.