nautechsystems/nautilus_trader · error · anyhow::Error

Failed to send UpdateInstrument command: {e}

Error message

Failed to send UpdateInstrument command: {e}

What it means

Raised when updating the handler's coin-to-instrument mapping via HandlerCommand::UpdateInstrument during a quote/BBO subscription: the mpsc send fails because the handler task's command receiver is gone, meaning the handler task has stopped. The method rolls back the just-inserted quote_streams entry and propagates the error, leaving the client without the subscription.

Source

Thrown at crates/adapters/hyperliquid/src/websocket/client.rs:1448

            .map_err(|e| anyhow::anyhow!("Failed to send SetDepth10Sub command: {e}"))?;

        self.send_book_stream_unsubscribe(&cmd_tx, coin, BookStreamUse::Depth10)
    }

    /// Subscribe to best bid/offer (BBO) quotes for an instrument.
    pub async fn subscribe_quotes(&self, instrument_id: InstrumentId) -> anyhow::Result<()> {
        let instrument = self
            .get_instrument(&instrument_id)
            .ok_or_else(|| InstrumentLookupError::not_found(instrument_id))?;
        let coin = instrument.raw_symbol().inner();

        let cmd_tx = self.cmd_tx.read().await;
        self.quote_streams.insert(coin, ());

        // Update the handler's coin→instrument mapping for this subscription
        if let Err(e) = cmd_tx.send(HandlerCommand::UpdateInstrument(instrument.clone())) {
            self.quote_streams.remove(&coin);
            anyhow::bail!("Failed to send UpdateInstrument command: {e}");
        }

        let subscription = SubscriptionRequest::Bbo { coin };

        if let Err(e) = self.send_subscription(&cmd_tx, subscription) {
            self.quote_streams.remove(&coin);
            return Err(e);
        }
        Ok(())
    }

    /// Subscribe to all mid prices across markets.
    pub async fn subscribe_all_mids(&self) -> anyhow::Result<()> {
        self.subscribe_all_mids_with_dex(None).await
    }

    /// Subscribe to aggregate asset contexts across all perp dexes.
    pub async fn subscribe_all_dexs_asset_ctxs(&self) -> anyhow::Result<()> {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check connection state before subscribing and reconnect (or recreate the client) if the handler is down, then retry the subscription.
  2. Look for a preceding handler panic/exit in logs and fix that root cause.
  3. Avoid racing disconnect() with subscribe(); sequence them or check a connection flag first.
  4. Surface this error to the caller rather than ignoring it, since quote streams will not flow.

Example fix

// before: subscribe on dead handler task / client.subscribe_quote_streams(coin, instrument).await?; / // after: re-establish handler first / if !client.is_connected() { client.connect().await?; } / client.subscribe_quote_streams(coin, instrument).await?;
Defensive patterns

Strategy: validation

Validate before calling

fn can_subscribe(cmd_tx: &tokio::sync::mpsc::Sender<HandlerCommand>) -> bool { !cmd_tx.is_closed() }

Type guard

fn is_subscribable(client: &HyperliquidWebSocketClient) -> bool { client.is_connected() }

Try / catch

match client.subscribe_quote_streams(coin, instrument).await { Err(e) if e.to_string().contains("UpdateInstrument command") => { client.connect().await?; client.subscribe_quote_streams(coin, instrument).await?; } Err(e) => return Err(e.into()), Ok(()) => {} }

Prevention

When it happens

Trigger: Calling the quote-stream subscription method when the handler task has exited (receiver dropped): after a disconnect, after a handler crash, or on a client whose handler already shut down.

Common situations: Subscribing on a disconnected or never-connected client; a handler panic killed the task mid-session; concurrent disconnect() racing subscribe(); stale client reused after a network failure terminated the handler.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/e0a1f85861725c4c. Report an issue: GitHub.