{"record":{"id":"e0a1f85861725c4c","repo":"nautechsystems/nautilus_trader","slug":"failed-to-send-updateinstrument-command-e","errorCode":null,"errorMessage":"Failed to send UpdateInstrument command: {e}","messagePattern":"Failed to send UpdateInstrument command: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/hyperliquid/src/websocket/client.rs","lineNumber":1448,"sourceCode":"            .map_err(|e| anyhow::anyhow!(\"Failed to send SetDepth10Sub command: {e}\"))?;\n\n        self.send_book_stream_unsubscribe(&cmd_tx, coin, BookStreamUse::Depth10)\n    }\n\n    /// Subscribe to best bid/offer (BBO) quotes for an instrument.\n    pub async fn subscribe_quotes(&self, instrument_id: InstrumentId) -> anyhow::Result<()> {\n        let instrument = self\n            .get_instrument(&instrument_id)\n            .ok_or_else(|| InstrumentLookupError::not_found(instrument_id))?;\n        let coin = instrument.raw_symbol().inner();\n\n        let cmd_tx = self.cmd_tx.read().await;\n        self.quote_streams.insert(coin, ());\n\n        // Update the handler's coin→instrument mapping for this subscription\n        if let Err(e) = cmd_tx.send(HandlerCommand::UpdateInstrument(instrument.clone())) {\n            self.quote_streams.remove(&coin);\n            anyhow::bail!(\"Failed to send UpdateInstrument command: {e}\");\n        }\n\n        let subscription = SubscriptionRequest::Bbo { coin };\n\n        if let Err(e) = self.send_subscription(&cmd_tx, subscription) {\n            self.quote_streams.remove(&coin);\n            return Err(e);\n        }\n        Ok(())\n    }\n\n    /// Subscribe to all mid prices across markets.\n    pub async fn subscribe_all_mids(&self) -> anyhow::Result<()> {\n        self.subscribe_all_mids_with_dex(None).await\n    }\n\n    /// Subscribe to aggregate asset contexts across all perp dexes.\n    pub async fn subscribe_all_dexs_asset_ctxs(&self) -> anyhow::Result<()> {","sourceCodeStart":1430,"sourceCodeEnd":1466,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/hyperliquid/src/websocket/client.rs#L1430-L1466","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check connection state before subscribing and reconnect (or recreate the client) if the handler is down, then retry the subscription.","Look for a preceding handler panic/exit in logs and fix that root cause.","Avoid racing disconnect() with subscribe(); sequence them or check a connection flag first.","Surface this error to the caller rather than ignoring it, since quote streams will not flow."],"exampleFix":"// 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?;","handlingStrategy":"validation","validationCode":"fn can_subscribe(cmd_tx: &tokio::sync::mpsc::Sender<HandlerCommand>) -> bool { !cmd_tx.is_closed() }","typeGuard":"fn is_subscribable(client: &HyperliquidWebSocketClient) -> bool { client.is_connected() }","tryCatchPattern":"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(()) => {} }","preventionTips":["Check connection state before every subscription call.","Reconnect promptly after disconnect/errors instead of reusing the dead client.","Avoid racing disconnect() against subscribe() in concurrent code.","Alert on this error; the subscription silently will not deliver quotes if ignored."],"tags":["websocket","async","channel-closed","subscription"],"backgroundTag":"connection-refused","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}