nautechsystems/nautilus_trader · error · anyhow::Error
WS message receiver not available after connect
Error message
WS message receiver not available after connect
What it means
After the WebSocket handshake and optional new-markets subscription, connect_client calls ws_client.take_message_receiver() which hands over the mpsc receiver exactly once. If it returns None, the WS client did not produce/hold a message receiver after connecting — an internal invariant breach — so connect fails.
Source
Thrown at crates/adapters/polymarket/src/data/lifecycle.rs:541
log::info!("Connecting Polymarket data client");
log::debug!("Bootstrapping instruments from Gamma API...");
self.bootstrap_instruments().await?;
log::debug!(
"Bootstrap complete, {} instruments loaded",
self.instruments.load().len(),
);
self.ws_client.connect().await?;
let session_result = async {
if self.config.subscribe_new_markets {
log::debug!("Subscribing to new markets...");
self.ws_client.subscribe_new_markets_feed().await?;
}
let rx = self.ws_client.take_message_receiver().ok_or_else(|| {
anyhow::anyhow!("WS message receiver not available after connect")
})?;
self.register_message_handler(rx)?;
self.register_instrument_refresh_task()?;
self.register_resolve_poll_task()?;
// Connect unconditionally: this clears the feed's closing latch from a prior
// disconnect; without retained subscriptions no RTDS socket is opened.
self.rtds_feed.connect().await
}
.await;
if let Err(e) = session_result {
if let Err(teardown_error) = self.disconnect_client().await {
log::warn!(
"Error tearing down partial Polymarket data connection: {teardown_error:?}"
);
}View on GitHub (pinned to 18893faf8b)
Solutions
- Do not share or reuse ws_client handles across connect cycles; create a fresh client per connection
- Avoid concurrent connect() calls on the same client
- Rebuild the client if a previous connect consumed the receiver without completing
- Check the WS client construction path to ensure the message channel is always installed
Example fix
// before let rx1 = ws.take_message_receiver(); // first connect let rx2 = ws.take_message_receiver(); // None -> error // after let client = PolymarketDataClient::new(...)?; // fresh client per connect client.connect().await?;
Defensive patterns
Strategy: validation
Validate before calling
// before connect, ensure this is a fresh client and no other connect is in flight assert!(!connect_in_progress.load(Ordering::SeqCst));
Type guard
fn receiver_expected(ws: &PolymarketWsClient) -> bool { !ws.receiver_taken() } Try / catch
if let Err(e) = client.connect().await {
if e.to_string().contains("receiver not available") {
// receiver already consumed: must rebuild client
client = build_client(cfg)?;
client.connect().await?;
}
} Prevention
- Never reuse a client/ws handle whose connect already consumed the message receiver
- Protect connect() with a mutex or atomic so it cannot run twice concurrently
- Construct a new data client for each connection cycle
When it happens
Trigger: take_message_receiver() returns None after a successful WS connect: receiver already taken (double connect on the same ws_client handle), or the underlying WS client was reused/replaced and never set a new receiver.
Common situations: Reusing a data client (or manually its ws_client) across connect attempts without reconstruction; calling connect twice concurrently so one connect consumes the receiver; constructing the client against a ws_client that failed to initialize its channel.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- noid '{}' does not match new order oid '{}'
- RTDS WebSocket client unavailable after reconcile
- conflicting RTDS TWAP observation topic={} symbol={} timesta
- Unsupported RTDS custom data type: {other}
- Failed to start Polymarket WebSocket handler task: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/c55a922e0ed41cee.
Report an issue: GitHub.