nautechsystems/nautilus_trader · error
Failed to start Coinbase poll generation: {e}
Error message
Failed to start Coinbase poll generation: {e} What it means
After finishing the previous shutdown in `prepare`, the adapter calls `start_generation` to open a new generation of poll tasks. Failure there (task-set state machine refused to start) is wrapped in this error.
Source
Thrown at crates/adapters/coinbase/src/data/poll.rs:144
entry.cancel.cancel();
// Replace the now-cancelled token so a later `resume()` can
// spawn a fresh task that listens on a live token.
entry.cancel = CancellationToken::new();
}
}
self.tasks.begin_shutdown();
}
pub(crate) async fn prepare(&self) -> anyhow::Result<()> {
if !self.tasks.is_open() {
self.tasks
.finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))
.await
.map_err(|e| anyhow::anyhow!("Failed to finish Coinbase poll tasks: {e}"))?;
self.tasks
.start_generation()
.map_err(|e| anyhow::anyhow!("Failed to start Coinbase poll generation: {e}"))?;
}
Ok(())
}
pub(crate) async fn finish_shutdown(&self) -> anyhow::Result<()> {
self.tasks
.finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))
.await
.map_err(|e| anyhow::anyhow!("Failed to finish Coinbase poll tasks: {e}"))?;
Ok(())
}
/// Spawns polling tasks for every entry with at least one active flag.
/// Called from `connect()` so subscriptions made before a
/// `disconnect()` remain live after the client reconnects: the data
/// engine suppresses duplicate subscribe commands, so the caller does
/// not re-issue them.
pub(crate) fn resume(&self) {View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure connect is not called concurrently (serialize with a mutex or single task)
- Verify the preceding finish_shutdown fully completed before retrying
- Recreate the client instance if its task-set state is wedged
- Check logs for the inner `{e}` from start_generation
Example fix
// before
for sym in symbols {
tokio::spawn(client.connect()); // concurrent connects
}
// after
client.connect().await?; // single serialized connect Defensive patterns
Strategy: try-catch
Try / catch
match client.prepare().await {
Err(e) if e.to_string().contains("Failed to start Coinbase poll generation") => {
// state race: recreate client
client = recreate_client(config).await?;
}
other => other?,
} Prevention
- Never call connect/prepare from multiple tasks concurrently
- Wrap reconnection in a single supervisor task
- Treat a wedged task set as fatal and rebuild the client
When it happens
Trigger: connect/prepare invoked when the task set's internal state forbids starting a new generation — e.g. shutdown not fully completed despite finish_shutdown returning Ok, or concurrent start_generation calls.
Common situations: Concurrent connect() calls from different tasks; reconnecting immediately after disconnect when generation counters are out of sync.
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 finish Coinbase poll tasks: {e}
- Failed to start Coinbase task generation: {e}
- Already running
- Failed to start Betfair data session tasks: {e}
- Failed to start Betfair data command tasks: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/521529ef17f61af9.
Report an issue: GitHub.