{"record":{"id":"621dc1c3a4980850","repo":"nautechsystems/nautilus_trader","slug":"unsubscribe-market-requires-a-market-channel-cli","errorCode":null,"errorMessage":"unsubscribe_market() requires a market-channel client (created with new_market())","messagePattern":"unsubscribe_market\\(\\) requires a market-channel client \\(created with new_market\\(\\)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/websocket/client.rs","lineNumber":544,"sourceCode":"        }\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    /// Remove asset IDs from the active subscription set.\n    ///\n    /// The IDs are dropped from the reconnect set so they will not be\n    /// re-subscribed after a reconnect. No wire message is sent.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if called on a user-channel client (incompatible channel).\n    pub async fn unsubscribe_market(&self, asset_ids: Vec<String>) -> anyhow::Result<()> {\n        if self.channel != WsChannel::Market {\n            anyhow::bail!(\n                \"unsubscribe_market() requires a market-channel client (created with new_market())\"\n            );\n        }\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    /// Authenticate and subscribe to the user channel.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if called on a market-channel client (no credentials available).\n    pub async fn subscribe_user(&self) -> anyhow::Result<()> {\n        if self.channel != WsChannel::User {\n            anyhow::bail!(","sourceCodeStart":526,"sourceCodeEnd":562,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/websocket/client.rs#L526-L562","documentation":"unsubscribe_market sends a market-channel unsubscribe command and is only valid on a client configured for the market channel. On a user-channel client there is no asset-id market subscription to remove, so the call is rejected up front.","triggerScenarios":"Calling unsubscribe_market(asset_ids) on a client built with new_user() (WsChannel::User), typically to tear down subscriptions that were never made on that client.","commonSituations":"Cleanup/shutdown code that calls both unsubscribe_market and unsubscribe_user on every client regardless of channel; wrong client instance passed to a teardown helper.","solutions":["Only call unsubscribe_market on clients created with new_market(); use unsubscribe_user for user-channel clients","Track the channel of each client and branch teardown logic on it","Check the channel field before calling to avoid the error"],"exampleFix":"// before\nclient.unsubscribe_market(asset_ids).await?;\nclient.unsubscribe_user().await?;\n// after\nmatch client.channel() {\n    WsChannel::Market => client.unsubscribe_market(asset_ids).await?,\n    WsChannel::User => client.unsubscribe_user().await?,\n}","handlingStrategy":"validation","validationCode":"if client.channel() == WsChannel::Market {\n    client.unsubscribe_market(asset_ids).await?;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Branch teardown logic on the client's channel","Only unsubscribe what you actually subscribed on that client"],"tags":["rust","websocket","polymarket","channel-mismatch"],"backgroundTag":"invalid-state-transition","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"}