nautechsystems/nautilus_trader · error

subscribe_market() requires a market-channel client (created

Error message

subscribe_market() requires a market-channel client (created with new_market())

What it means

PolymarketWebSocketClient is built either for the market channel (new_market) or the user channel (new_user); each channel has its own subscription message schema. subscribe_market checks the configured channel and refuses to run on a user-channel client because the command would be invalid for that connection.

Source

Thrown at crates/adapters/polymarket/src/websocket/client.rs:523

    }

    /// Returns `true` if the user channel has been authenticated.
    #[must_use]
    pub fn is_authenticated(&self) -> bool {
        self.auth_tracker.is_authenticated()
    }

    /// Subscribe to market data for the given asset IDs.
    ///
    /// Sends a subscribe message immediately if connected; the IDs are also
    /// retained so they are re-sent automatically on reconnect.
    ///
    /// # Errors
    ///
    /// Returns an error if called on a user-channel client (incompatible channel).
    pub async fn subscribe_market(&self, asset_ids: Vec<String>) -> anyhow::Result<()> {
        if self.channel != WsChannel::Market {
            anyhow::bail!(
                "subscribe_market() requires a market-channel client (created with new_market())"
            );
        }
        self.cmd_tx
            .read()
            .await
            .send(HandlerCommand::SubscribeMarket(asset_ids))
            .map_err(|e| anyhow::anyhow!("Failed to send SubscribeMarket: {e}"))
    }

    /// Remove asset IDs from the active subscription set.
    ///
    /// The IDs are dropped from the reconnect set so they will not be
    /// re-subscribed after a reconnect. No wire message is sent.
    ///
    /// # Errors
    ///
    /// Returns an error if called on a user-channel client (incompatible channel).

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Create the client with PolymarketWebSocketClient::new_market() before subscribing to market data
  2. Keep separate market-channel and user-channel clients and route each subscription call to the right instance
  3. Check client.channel (or is_market()/is_user() helpers) before calling subscribe_market

Example fix

// before
let client = PolymarketWebSocketClient::new_user(creds);
client.subscribe_market(asset_ids).await?;
// after
let client = PolymarketWebSocketClient::new_market().await?;
client.subscribe_market(asset_ids).await?;
Defensive patterns

Strategy: validation

Validate before calling

if client.channel() != WsChannel::Market {
    anyhow::bail!("subscribe_market needs a new_market() client");
}
client.subscribe_market(asset_ids).await?;

Prevention

When it happens

Trigger: Calling subscribe_market(asset_ids) on a client constructed with PolymarketWebSocketClient::new_user() (or otherwise configured as WsChannel::User).

Common situations: Mixing up client constructors when wiring multiple connections; reusing one client for both book data and order/fill updates; copy-pasted client setup where the user-channel client is passed to a data-engine that calls subscribe_market.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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