{"record":{"id":"1ab461e01f68ad29","repo":"nautechsystems/nautilus_trader","slug":"failed-to-send-subscribemarket-e","errorCode":null,"errorMessage":"Failed to send SubscribeMarket: {e}","messagePattern":"Failed to send SubscribeMarket: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/websocket/client.rs","lineNumber":78,"sourceCode":"    User,\n}\n\n/// Lightweight handle for subscribing/unsubscribing to market data.\n///\n/// `Clone` + `Send` safe for use in spawned async tasks.\n#[derive(Clone, Debug)]\npub struct WsSubscriptionHandle {\n    cmd_tx: Arc<tokio::sync::RwLock<tokio::sync::mpsc::UnboundedSender<HandlerCommand>>>,\n}\n\nimpl WsSubscriptionHandle {\n    /// Sends a market subscribe command to the handler.\n    pub async fn subscribe_market(&self, asset_ids: Vec<String>) -> anyhow::Result<()> {\n        self.cmd_tx\n            .read()\n            .await\n            .send(HandlerCommand::SubscribeMarket(asset_ids))\n            .map_err(|e| anyhow::anyhow!(\"Failed to send SubscribeMarket: {e}\"))\n    }\n\n    /// Sends a market unsubscribe command to the handler.\n    pub async fn unsubscribe_market(&self, asset_ids: Vec<String>) -> anyhow::Result<()> {\n        self.cmd_tx\n            .read()\n            .await\n            .send(HandlerCommand::UnsubscribeMarket(asset_ids))\n            .map_err(|e| anyhow::anyhow!(\"Failed to send UnsubscribeMarket: {e}\"))\n    }\n\n    // Constructs a handle around a raw command sender. Test-only: lets unit\n    // tests observe the commands the handle emits without spinning up the real\n    // feed handler.\n    #[cfg(test)]\n    pub(crate) fn from_sender(sender: tokio::sync::mpsc::UnboundedSender<HandlerCommand>) -> Self {\n        Self {\n            cmd_tx: Arc::new(tokio::sync::RwLock::new(sender)),","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/websocket/client.rs#L60-L96","documentation":"subscribe_market() enqueues a HandlerCommand::SubscribeMarket on the internal mpsc channel consumed by the background feed-handler task. The send only fails when the channel receiver has been dropped, i.e. the handler task has exited, so there is no live WebSocket session to receive the subscription. This converts the tokio SendError into an anyhow error for the caller.","triggerScenarios":"Calling subscribe_market() after disconnect(), before the first successful connect(), after the handler task panicked or returned an error (e.g. repeated connection failures killed it), or racing an in-flight disconnect from another task.","commonSituations":"A task subscribes while another task is disconnecting/reconnecting the client; the handler task died because the gateway endpoint was unreachable and was never restarted; forgetting that PolymarketWebSocketClient is not usable between disconnect() and connect().","solutions":["Check the client is connected (e.g. is_active()) before calling subscribe_market()","Call connect() again to respawn the handler task, then retry subscribe_market()","Remove the race between disconnect() and subscribe_market() (e.g. hold a lock or route all commands through one task)","Check logs from the handler task to find why it exited and fix the root cause"],"exampleFix":"// before\nclient.subscribe_market(asset_ids).await?; // panics/errors if handler stopped\n// after\nif !client.is_active() {\n    client.connect().await?;\n}\nclient.subscribe_market(asset_ids).await?;","handlingStrategy":"try-catch","validationCode":"// Rust\nif !client.is_active() {\n    client.connect().await?;\n}","typeGuard":null,"tryCatchPattern":"match client.subscribe_market(asset_ids).await {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"Failed to send SubscribeMarket\") => {\n        client.connect().await?; // handler gone: respawn and retry once\n        client.subscribe_market(asset_ids).await?;\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Check is_active() before any subscribe/unsubscribe call","Never interleave disconnect() and subscribe calls from different tasks without synchronization","Alert on handler task exits so you know the client is dead before commands fail","Subscribe immediately after connect() and rely on the reconnect replay set for later resubscribes"],"tags":["rust","websocket","channel","polymarket"],"backgroundTag":"channel-closed","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"}