nautechsystems/nautilus_trader · error · anyhow::Error

Market shard receiver unavailable after connect

Error message

Market shard receiver unavailable after connect

What it means

When the WebSocket shard pool grows (connect_new_shard), it creates a new market client, connects, and then must take ownership of the client's message receiver. If take_message_receiver returns None after a successful connect, the pool's internal invariant is broken — the receiver was already taken or was never set — so the shard cannot be brought up and this error aborts connect_new_shard (invoked from assign).

Source

Thrown at crates/adapters/polymarket/src/websocket/pool.rs:659

    async fn connect_new_shard(&self, is_primary: bool) -> anyhow::Result<usize> {
        if self.closed.load(Ordering::Acquire) {
            anyhow::bail!("Market connection pool is closed");
        }

        let id = if is_primary {
            PRIMARY_SHARD_ID
        } else {
            let state = self.state.lock();
            available_shard_id(&state)
        };

        let mut client = self.market_client(self.subscribe_new_markets, id);
        client.connect().await?;

        let handle = client.clone_subscription_handle();
        let rx = client
            .take_message_receiver()
            .ok_or_else(|| anyhow::anyhow!("Market shard receiver unavailable after connect"))?;
        let forwarder = match self.spawn_forwarder(rx, is_primary) {
            Ok(forwarder) => forwarder,
            Err((e, forwarder)) => {
                let shard = Box::new(ShardEntry {
                    client,
                    handle,
                    forwarder,
                    owned: 0,
                    closing: true,
                });

                if let Err(close_error) = self.close_shard(id, shard).await {
                    anyhow::bail!(
                        "Failed to start market shard forwarder: {e}; startup rollback failed: \
                         {close_error}"
                    );
                }
                anyhow::bail!("Failed to start market shard forwarder: {e}");

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check that each ShardEntry/market client is used exactly once — never reuse a connected client for another shard
  2. Guard pool resizing against concurrent assign calls (serialize shard creation)
  3. Upgrade the polymarket adapter — this indicates an internal invariant break that may be a fixed bug
  4. Capture the client state at failure and file an issue with logs if reproducible

Example fix

// before: panics the whole assign flow on None
let rx = client.take_message_receiver()
    .ok_or_else(|| anyhow::anyhow!("Market shard receiver unavailable after connect"))?;
// after: retry shard creation once
let rx = client.take_message_receiver()
    .or_else(|| { client.connect(); client.take_message_receiver() })
    .ok_or_else(|| anyhow::anyhow!("Market shard receiver unavailable after connect"))?;
Defensive patterns

Strategy: try-catch

Try / catch

match connect_new_shard(id).await {
    Ok(shard) => /* register shard */,
    Err(e) if e.to_string().contains("receiver unavailable") => {
        log::error!("pool invariant broken: {e}; rebuilding pool");
        // rebuild or restart the pool
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling connect_new_shard when the freshly constructed client's receiver channel was already consumed, or the client implementation changed so no receiver is created during connect().

Common situations: Concurrent pool resizing racing on the same client; a version mismatch/bug in the market client that skips receiver setup; reusing a client instance for a second shard.

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


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