nautechsystems/nautilus_trader · error · anyhow::Error
Failed to send UnsubscribeMarket
Error message
Failed to send UnsubscribeMarket: {e} What it means
unsubscribe_market() enqueues HandlerCommand::UnsubscribeMarket on the internal mpsc channel to the feed-handler task. It fails only when the receiver has been dropped because the handler task has exited, meaning there is no active session to process the unsubscribe.
Solutions
- Guard the call with a connected/is_active check
- If the client is down, the subscription is already gone — skip unsubscribe_market() and return Ok
- Call connect() first if you need the client live again, then unsubscribe
- Investigate why the handler task exited via its logs
Example fix
// before
client.unsubscribe_market(asset_ids).await?;
// after
if client.is_active() {
client.unsubscribe_market(asset_ids).await?;
} // else: subscription died with the session, nothing to unsubscribe Defensive patterns
Strategy: try-catch
Validate before calling
if client.is_active() {
client.unsubscribe_market(asset_ids).await?;
} Try / catch
if let Err(e) = client.unsubscribe_market(asset_ids).await {
// handler gone means the venue subscription is gone too; safe to ignore on shutdown
log::debug!("unsubscribe skipped, handler not running: {e:#}");
} Prevention
- Skip unsubscribe when the client is already disconnected — nothing to unsubscribe
- Centralize lifecycle (connect/disconnect/subscribe) in one owning task
- Treat this error as benign during shutdown paths
- Monitor handler task liveness to distinguish real failures from benign ones
When it happens
Trigger: Calling unsubscribe_market() after disconnect(), after the handler task terminated (panic or fatal connection error), or concurrently with a reconnect that replaces the handler task.
Common situations: Cleanup/shutdown code unsubscribing after the client was already disconnected; handler died earlier from a network outage; test harness dropping the client while an unsubscribe is in flight.
Related errors
- Failed to replay SubscribeUser
- Failed to send SubscribeMarket
- Failed to send SubscribeUser
- Book snapshot hash mismatch for
- conflicting RTDS TWAP observation topic=
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/73eceefbe336d4bb.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/polymarket/src/websocket/client.rs:87
}
impl WsSubscriptionHandle {
/// Sends a market subscribe command to the handler.
pub async fn subscribe_market(&self, asset_ids: Vec<String>) -> anyhow::Result<()> {
self.cmd_tx
.read()
.await
.send(HandlerCommand::SubscribeMarket(asset_ids))
.map_err(|e| anyhow::anyhow!("Failed to send SubscribeMarket: {e}"))
}
/// Sends a market unsubscribe command to the handler.
pub async fn unsubscribe_market(&self, asset_ids: Vec<String>) -> anyhow::Result<()> {
self.cmd_tx
.read()
.await
.send(HandlerCommand::UnsubscribeMarket(asset_ids))
.map_err(|e| anyhow::anyhow!("Failed to send UnsubscribeMarket: {e}"))
}
// Constructs a handle around a raw command sender. Test-only: lets unit
// tests observe the commands the handle emits without spinning up the real
// feed handler.
#[cfg(test)]
pub(crate) fn from_sender(sender: tokio::sync::mpsc::UnboundedSender<HandlerCommand>) -> Self {
Self {
cmd_tx: Arc::new(tokio::sync::RwLock::new(sender)),
}
}
}
/// Provides a WebSocket client for the Polymarket CLOB API.
///
/// A single instance targets one channel (market or user). Use
/// [`PolymarketWebSocketClient::new_market`] for public market data and
/// [`PolymarketWebSocketClient::new_user`] for authenticated order/trade streams.View on GitHub (pinned to 18893faf8b)