nautechsystems/nautilus_trader · error
Failed to start Coinbase task generation: {e}
Error message
Failed to start Coinbase task generation: {e} What it means
Inside connect(), after awaiting and terminating the previous pending-task generation, the client calls `start_generation` to open a fresh generation of execution tasks. If the task set refuses to start, this error is raised.
Source
Thrown at crates/adapters/coinbase/src/execution.rs:376
fn oms_type(&self) -> OmsType {
self.core.oms_type
}
fn get_account(&self) -> Option<AccountAny> {
self.core.cache().account_owned(&self.core.account_id)
}
async fn connect(&mut self) -> anyhow::Result<()> {
if self.core.is_connected() && self.pending_tasks.is_open() && self.session_tasks.is_open()
{
return Ok(());
}
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();
});View on GitHub (pinned to 18893faf8b)
Solutions
- Serialize connect() calls (single owner task or mutex)
- Ensure disconnect/finish_shutdown completed before reconnecting
- Read the inner `{e}` from start_generation in logs
- Recreate the execution client if the generation state is corrupted
- Check for concurrent engine start/stop racing the adapter
Example fix
// before
let c = client.clone();
tokio::spawn(async move { c.connect().await });
client.connect().await?; // duplicate connect
// after
client.connect().await?; // exactly one connect per client Defensive patterns
Strategy: try-catch
Try / catch
if let Err(e) = client.connect().await {
if e.to_string().contains("Failed to start Coinbase task generation") {
// unrecoverable state race: rebuild client
client = CoinbaseExecClient::new(...).await?;
client.connect().await?;
} else { return Err(e); }
} Prevention
- Give exactly one component ownership of connect()/disconnect()
- Always disconnect before reconnecting; never skip teardown
- Guard against engine restart races on the same adapter instance
When it happens
Trigger: connect() invoked when the pending task set is closed but its internal state does not permit starting a new generation — e.g. shutdown not fully observed, or concurrent connect calls racing on the same task set.
Common situations: Two components calling connect() on the same execution client simultaneously; reconnect logic that skips proper disconnect/teardown ordering.
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 start Coinbase poll generation: {e}
- Failed to terminate Coinbase execution tasks: {e}
- std::mem::take(&mut self.shutdown_errors).join("; ")
- Already running
- Failed to start Betfair data session tasks: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/0ebdeba8ae9629dc.
Report an issue: GitHub.