nautechsystems/nautilus_trader · error

Polymarket execution shutdown failed: {}

Error message

Polymarket execution shutdown failed: {}

What it means

During Polymarket execution client teardown, any error collected while stopping sub-components (streams, websocket, orders cache) is accumulated in shutdown_errors and reported together at the end. teardown_partial_connect returns Ok only when shutdown was fully clean; otherwise it aggregates all shutdown errors into one anyhow error. This ensures a partially failed disconnect is never silently swallowed.

Source

Thrown at crates/adapters/polymarket/src/execution/lifecycle.rs:439

        if let Err(e) = self.ws_client.disconnect().await {
            self.shutdown_errors.push(e.to_string());
        }

        if let Err(e) = self.await_session_tasks().await {
            self.shutdown_errors.push(e.to_string());
        }

        if let Err(e) = self.await_pending_tasks().await {
            self.shutdown_errors.push(e.to_string());
        }
        self.core.set_disconnected();

        if self.shutdown_errors.is_empty() {
            Ok(())
        } else {
            let errors = std::mem::take(&mut self.shutdown_errors);
            anyhow::bail!(
                "Polymarket execution shutdown failed: {}",
                errors.join("; ")
            )
        }
    }

    pub(super) fn get_neg_risk(&self, instrument_id: &InstrumentId) -> bool {
        self.neg_risk_index
            .get_cloned(instrument_id)
            .unwrap_or(false)
    }

    pub(super) fn get_neg_risk_from_snapshot(
        neg_risk_index: &AHashMap<InstrumentId, bool>,
        instrument_id: &InstrumentId,
    ) -> bool {
        neg_risk_index.get(instrument_id).copied().unwrap_or(false)
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the joined error list in the message to see which specific shutdown step(s) failed
  2. Verify network connectivity and that the Polymarket endpoints are reachable during disconnect
  3. Check logs for the underlying component errors preceding this aggregate message
  4. Retry disconnect after a short delay; ensure idempotent teardown if errors persist
  5. If it occurs on a stale client, discard the client and build a fresh connection instead of retrying teardown

Example fix

// before
match client.disconnect().await {
    Err(e) => log::warn("ignored shutdown error: {e}"),
    Ok(_) => {},
}
// after
if let Err(e) = client.disconnect().await {
    log::error!("Polymarket execution shutdown failed: {e:#}");
    return Err(e); // propagate instead of swallowing, so state isn't assumed clean
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: ensure the client is connected and tasks are healthy before disconnect
if !client.is_connected() {
    log::warn!("client already disconnected; skipping teardown");
    return Ok(());
}

Try / catch

match client.disconnect().await {
    Ok(()) => info!("shutdown clean"),
    Err(e) => {
        // message contains the joined per-step shutdown errors
        error!("shutdown failed: {e:#}");
        // mark state disconnected and rebuild client rather than reusing
    }
}

Prevention

When it happens

Trigger: Calling connect_client or disconnect_client when one or more shutdown steps fail (e.g. websocket close fails, stream task join errors), causing shutdown_errors to be non-empty when the final check runs.

Common situations: Network already down when disconnecting; Polymarket CLOB/WebSocket endpoints unreachable mid-teardown; reconnect loops where a previous partial connect leaves tasks that fail to stop cleanly; process shutdown racing with active subscriptions.

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


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