nautechsystems/nautilus_trader · error
Failed to start Coinbase session generation: {e}
Error message
Failed to start Coinbase session generation: {e} What it means
Raised in CoinbaseExecutionClient::connect when TaskGroup::start_generation() fails while re-establishing the user WebSocket session after closing a stale one. It wraps the underlying task-group error (e.g. a generation is already running or the group was shut down) into an anyhow error that aborts the connect flow.
Source
Thrown at crates/adapters/coinbase/src/execution.rs:388
}
if !self.pending_tasks.is_open() {
self.await_pending_tasks().await?;
self.pending_tasks
.start_generation()
.map_err(|e| anyhow::anyhow!("Failed to start Coinbase task generation: {e}"))?;
}
if !self.session_tasks.is_open() || !self.session_tasks.is_empty() {
self.abort_session_tasks();
self.ws_user
.disconnect()
.await
.context("failed to close stale Coinbase user WebSocket")?;
self.await_session_tasks().await?;
self.session_tasks
.start_generation()
.map_err(|e| anyhow::anyhow!("Failed to start Coinbase session generation: {e}"))?;
}
let ws_user = self.ws_user.clone();
let setup_guard =
TaskGroupGuard::new(&[&self.session_tasks, &self.pending_tasks], move || {
ws_user.begin_shutdown();
});
// If the underlying WS is still alive from a prior stop() that did not
// explicitly disconnect, tear it down before reconnecting. The
// in-handler signal path can race with the Disconnect command, leaving
// the inner connection_mode stale even after disconnect().await, so
// we rebuild the client outright to guarantee clean cmd_tx/out_rx
// pairs and a fresh signal.
if self.ws_user.is_active() || self.ws_user.is_reconnecting() {
log::debug!("Tearing down stale user WS before reconnect");
self.ws_user
.disconnect()
.awaitView on GitHub (pinned to 18893faf8b)
Solutions
- Ensure disconnect() is fully awaited before calling connect() again so the previous session generation ends.
- Check the wrapped {e} source for 'already started' style TaskGroup errors and serialize your connect calls.
- Await await_session_tasks()/join on prior session tasks before reconnecting.
- If the client is permanently stopped, create a fresh client instance instead of reconnecting.
Example fix
// before
client.connect().await?;
// after (serialize reconnects)
if client.is_connected() { client.disconnect().await?; }
client.connect().await?; Defensive patterns
Strategy: try-catch
Validate before calling
if client_is_connected() { tokio::time::timeout(Duration::from_secs(10), client.disconnect()).await.expect("disconnect timed out"); } Type guard
fn can_start_generation(joined: bool, stopped: bool) -> bool { !joined && !stopped } Try / catch
match client.connect().await {
Ok(_) => {},
Err(e) if e.to_string().contains("session generation") => { /* serialize reconnect: wait for prior tasks, then retry once */ }
Err(e) => return Err(e),
} Prevention
- Always await disconnect() fully before reconnecting.
- Serialize connect calls with a mutex/once flag per client.
- Log and join session tasks during shutdown paths.
When it happens
Trigger: Calling connect() on a Coinbase execution client whose session_tasks TaskGroup is already in a running generation, or in a state (stopping/stopped) that refuses a new generation start.
Common situations: Double-connecting the same client (e.g. reconnect logic racing with an existing connection), restarting a live node without awaiting the prior disconnect, or framework lifecycle code calling connect twice.
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
- Failed to terminate Hyperliquid execution session tasks: {e}
- subscription state lock poisoned
- InstrumentState channel requires kind and currency parameter
- std::mem::take(&mut self.shutdown_errors).join("; ")
- noid '{}' does not match new order oid '{}'
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/1674ef2f8752da62.
Report an issue: GitHub.