nautechsystems/nautilus_trader · error
No primary market shard available for new-market discovery
Error message
No primary market shard available for new-market discovery
What it means
The Polymarket market connection pool maintains a designated 'primary' shard used for discovering newly listed markets (subscribing with an empty asset list). This error means no shard with PRIMARY_SHARD_ID exists in the pool when subscribe_new_markets_feed is called — either the pool has not connected yet or the primary shard was closed and not re-established.
Source
Thrown at crates/adapters/polymarket/src/websocket/pool.rs:288
///
/// Returns an error if no primary shard is available.
pub async fn subscribe_new_markets_feed(&self) -> anyhow::Result<()> {
let _wire = self.inner.wire_mutex.lock().await;
let handle = {
let state = self.inner.state.lock();
if self.inner.closed.load(Ordering::Acquire) {
anyhow::bail!("Market connection pool is closed");
}
state
.shards
.get(&PRIMARY_SHARD_ID)
.map(|shard| shard.handle.clone())
};
match handle {
Some(handle) => handle.subscribe_market(vec![]).await,
None => anyhow::bail!("No primary market shard available for new-market discovery"),
}
}
/// Takes the merged message receiver, leaving `None` in its place.
#[must_use]
pub fn take_message_receiver(
&self,
) -> Option<tokio::sync::mpsc::UnboundedReceiver<PolymarketWsMessage>> {
self.inner.out_rx.lock().take()
}
/// Disconnects every shard and clears routing state.
///
/// # Errors
///
/// Returns an error after attempting every shard when a task or connection does not stop.
pub async fn disconnect(&self) -> anyhow::Result<()> {
self.inner.begin_shutdown();View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure pool.connect() has completed successfully before calling subscribe_new_markets_feed
- Reconnect the pool (call connect) to re-establish the primary shard, then retry the subscription
- Check shard lifecycle: if the primary shard was closed by error/rebalance, verify connect_new_shard(PRIMARY_SHARD_ID) is invoked again
- Guard the call by checking the pool's primary shard state before subscribing
Example fix
// before let pool = MarketPool::new(config); pool.subscribe_new_markets_feed().await?; // no primary shard yet // after let pool = MarketPool::new(config); pool.connect().await?; // establishes primary shard pool.subscribe_new_markets_feed().await?;
Defensive patterns
Strategy: fallback
Validate before calling
// ensure the primary shard exists before subscribing
if pool.primary_shard_handle().is_none() {
pool.connect().await?;
} Try / catch
match pool.subscribe_new_markets_feed().await {
Ok(rx) => { /* use feed */ }
Err(e) if e.to_string().contains("No primary market shard") => {
pool.connect().await?;
pool.subscribe_new_markets_feed().await?;
}
Err(e) => return Err(e),
} Prevention
- Always call connect() before any subscribe API
- Reconnect the pool after observed shard closures
- Treat discovery subscription as dependent on primary shard health
- Monitor shard connectivity in long-running sessions
When it happens
Trigger: Calling subscribe_new_markets_feed before connect() has established the primary market shard, or after the primary shard was closed/removed by pool rebalancing without being reopened.
Common situations: Calling discovery subscription immediately after constructing the pool without connecting; a dropped WebSocket killed the primary shard and it was never restarted; calling the feed after disconnect.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Polymarket data shutdown failed: {}
- Expected BinaryOption, was {other:?}
- RTDS task owner was dropped
- Polymarket RTDS task owner was dropped
- RTDS WebSocket client unavailable after reconcile
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/78459c6eeab9ce20.
Report an issue: GitHub.