nautechsystems/nautilus_trader · error · anyhow::Error
Polymarket session task admission is closed: {e}
Error message
Polymarket session task admission is closed: {e} What it means
Before spawning the WebSocket dispatch task, `start_ws_stream` acquires a spawner from the `session_tasks` task group. If the task group's admission is closed (shutdown has begun), `spawner()` fails and this error is returned. It means the adapter is shutting down or not yet restarted for a new generation, so no new session tasks can be admitted.
Source
Thrown at crates/adapters/polymarket/src/execution/lifecycle.rs:319
let http_client = self.http_client.clone();
let clock = self.clock;
let signature_type = self.config.signature_type;
let stopping = self.stopping.clone();
let user_address = self
.secrets
.funder
.clone()
.unwrap_or_else(|| self.secrets.address.clone());
let user_api_key = SecretString::from(self.secrets.credential.api_key_str().to_string());
let fill_tracker = self.fill_tracker.clone();
let pending_submits = self.pending_submits.clone();
let order_contexts = self.order_contexts.clone();
let ws_dispatch_state = self.ws_dispatch_state.clone();
let session_spawner = self
.session_tasks
.spawner()
.map_err(|e| anyhow::anyhow!("Polymarket session task admission is closed: {e}"))?;
if let Err(e) = self.session_tasks.spawn(async move {
let ctx = WsDispatchContext {
token_instruments: &token_instruments,
fill_tracker: &fill_tracker,
pending_submits: &pending_submits,
order_contexts: &order_contexts,
emitter: &emitter,
account_id,
clock,
user_address: &user_address,
user_api_key: user_api_key.expose_secret(),
};
loop {
match rx.recv().await {
Some(PolymarketWsMessage::User(user_msg)) => {
let refresh = {View on GitHub (pinned to 18893faf8b)
Solutions
- Do not call connect while the client is stopping; check the stopping flag/state before connecting
- Ensure connect_client's start_generation path runs (reopening admission) before spawning session tasks
- Serialize connect/disconnect calls behind a lock or the existing setup_guard
- Retry connect after the shutdown generation has fully finished
Example fix
// before: connecting during shutdown
if stopping { return; }
adapter.connect().await?;
// after: guard against closed admission with proper lifecycle ordering
if adapter.is_stopping() {
return; // refuse connect during teardown
}
adapter.connect().await?; Defensive patterns
Strategy: try-catch
Validate before calling
// refuse connect while adapter is stopping
if adapter.is_stopping() { return Err(anyhow!("cannot connect during shutdown")); } Try / catch
match adapter.connect().await {
Err(e) if e.to_string().contains("admission is closed") => {
// wait for shutdown generation to finish, then retry
tokio::time::sleep(Duration::from_secs(1)).await;
}
other => other?,
} Prevention
- Do not interleave connect and disconnect concurrently
- Check the stopping flag/state before connecting
- Await full teardown completion before reconnect attempts
When it happens
Trigger: Calling connect_client after await_session_tasks/begin_shutdown has closed session-task admission and before start_generation reopens it; a racing teardown closing the group while connect is in progress.
Common situations: Concurrent connect and disconnect calls on the execution client; reconnect attempt issued during adapter shutdown; stop flag set while a connect is still completing.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Already running
- Failed to start Betfair data session tasks: {e}
- Failed to start Betfair data command tasks: {e}
- Failed to start Coinbase poll generation: {e}
- Failed to start Coinbase task generation: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/8b7aee3652ec4a03.
Report an issue: GitHub.