{"record":{"id":"90e9cb94189adef5","repo":"nautechsystems/nautilus_trader","slug":"market-connection-pool-is-closed","errorCode":null,"errorMessage":"Market connection pool is closed","messagePattern":"Market connection pool is closed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/websocket/pool.rs","lineNumber":278,"sourceCode":"        *self.inner.out_tx.lock() = Some(out_tx);\n        *self.inner.out_rx.lock() = Some(out_rx);\n\n        self.inner.connect_new_shard(true).await?;\n        Ok(())\n    }\n\n    /// Sends the new-market discovery subscribe on the primary shard.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if no primary shard is available.\n    pub async fn subscribe_new_markets_feed(&self) -> anyhow::Result<()> {\n        let _wire = self.inner.wire_mutex.lock().await;\n\n        let handle = {\n            let state = self.inner.state.lock();\n            if self.inner.closed.load(Ordering::Acquire) {\n                anyhow::bail!(\"Market connection pool is closed\");\n            }\n            state\n                .shards\n                .get(&PRIMARY_SHARD_ID)\n                .map(|shard| shard.handle.clone())\n        };\n\n        match handle {\n            Some(handle) => handle.subscribe_market(vec![]).await,\n            None => anyhow::bail!(\"No primary market shard available for new-market discovery\"),\n        }\n    }\n\n    /// Takes the merged message receiver, leaving `None` in its place.\n    #[must_use]\n    pub fn take_message_receiver(\n        &self,\n    ) -> Option<tokio::sync::mpsc::UnboundedReceiver<PolymarketWsMessage>> {","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/websocket/pool.rs#L260-L296","documentation":"PolymarketConnectionPool serializes subscriptions with wire_mutex and tracks a closed flag. subscribe_new_markets_feed first takes the wire lock, then checks `closed`; if the pool has already been shut down it cannot establish the new-markets feed and returns this error instead.","triggerScenarios":"Calling subscribe_new_markets_feed() on a pool after disconnect()/close() was invoked (or the pool auto-closed), or on a stale pool reference retained past shutdown.","commonSituations":"Shutdown ordering bugs where a background task subscribes to the new-markets feed after the pool is closed; reconnect logic operating on an old pool instance; keeping the pool alive across a trader stop/start cycle.","solutions":["Check pool.is_closed() (or equivalent) before subscribing, and recreate the pool with connect() if closed","Fix shutdown ordering so subscribers stop before the pool is disconnected","Recreate or reconnect the pool and retry subscribe_new_markets_feed","Hold a single long-lived pool reference instead of caching disconnected instances"],"exampleFix":"// before\npool.subscribe_new_markets_feed().await?;\n// after\nif pool.is_closed() {\n    pool = PolymarketConnectionPool::connect(...).await?;\n}\npool.subscribe_new_markets_feed().await?;","handlingStrategy":"validation","validationCode":"if pool.is_closed() {\n    pool = PolymarketConnectionPool::connect(config).await?;\n}\npool.subscribe_new_markets_feed().await?;","typeGuard":null,"tryCatchPattern":"match pool.subscribe_new_markets_feed().await {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"pool is closed\") => {\n        let mut pool = pool;\n        pool = reconnect_pool().await?;\n        pool.subscribe_new_markets_feed().await?;\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Stop all subscriber tasks before closing the pool","Check the closed flag before any subscription call","Recreate the pool after disconnect instead of reusing the old instance"],"tags":["rust","websocket","pool","polymarket"],"backgroundTag":"invalid-state-transition","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}