nautechsystems/nautilus_trader · error
Failed to start Betfair data command tasks: {e}
Error message
Failed to start Betfair data command tasks: {e} What it means
Identical to error 1751 but for the command TaskGroup: command_tasks.start_generation() failed in prepare_task_groups. The command group hosts control-plane tasks (subscribes, commands); without a new generation, connect cannot spawn them.
Source
Thrown at crates/adapters/betfair/src/data.rs:242
self.command_tasks
.finish_shutdown(Duration::from_secs(1), Duration::from_secs(2)),
);
session_result
.map_err(|e| anyhow::anyhow!("Failed to finish Betfair data session tasks: {e}"))?;
command_result
.map_err(|e| anyhow::anyhow!("Failed to finish Betfair data command tasks: {e}"))?;
Ok(())
}
async fn prepare_task_groups(&mut self) -> anyhow::Result<()> {
if !self.session_tasks.is_open() || !self.command_tasks.is_open() {
self.teardown_partial_connect().await?;
self.session_tasks
.start_generation()
.map_err(|e| anyhow::anyhow!("Failed to start Betfair data session tasks: {e}"))?;
self.command_tasks
.start_generation()
.map_err(|e| anyhow::anyhow!("Failed to start Betfair data command tasks: {e}"))?;
}
Ok(())
}
fn begin_stream_shutdown(&self) {
for stream in self.stream_shutdowns.lock().iter() {
stream.begin_shutdown();
}
}
async fn teardown_partial_connect(&mut self) -> anyhow::Result<()> {
self.session_tasks.begin_shutdown();
self.command_tasks.begin_shutdown();
self.begin_stream_shutdown();
self.is_connected.store(false, Ordering::Relaxed);
if let Some(client) = self.cricket_stream_client.as_ref() {
client.close().await;View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the prior disconnect fully drained command tasks before reconnecting (finish_tasks completed without error)
- Read the inner `{e}` for the exact TaskGroup state reason
- Serialize connect/disconnect calls; do not run them concurrently on the same client
- If the group is permanently wedged, rebuild the BetfairDataClient
Example fix
// before
self.command_tasks.start_generation().map_err(|e| anyhow::anyhow!("Failed to start Betfair data command tasks: {e}"))?;
// after
if !self.command_tasks.is_open() {
self.command_tasks.start_generation().map_err(|e| anyhow::anyhow!("Failed to start Betfair data command tasks: {e}"))?;
} Defensive patterns
Strategy: retry
Validate before calling
// ensure no connect already in flight assert!(!client.is_connected(), "previous connect still active");
Try / catch
match client.connect().await {
Err(e) if e.to_string().contains("Failed to start Betfair data command tasks") => {
tokio::time::sleep(Duration::from_secs(2)).await;
client.disconnect().await.ok();
// then retry connect
}
Err(e) => return Err(e),
Ok(()) => {},
} Prevention
- Serialize connect/disconnect with a mutex or actor-style ownership
- Complete prior shutdowns before reconnecting
- Back off between attempts to let TaskGroup shutdown drain
- Rebuild the client if the command group stays wedged
When it happens
Trigger: connect() -> prepare_task_groups detects command_tasks.is_open() == false after teardown_partial_connect, then start_generation() returns Err because the group is not in a restartable state.
Common situations: Reconnect after a disconnect where the command group shutdown did not finalize; overlapping connect attempts; leftover shutdown errors from a prior failed teardown.
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 Betfair data session tasks: {e}
- Failed to start Betfair session generation: {e}
- Failed to start Betfair task generation: {e}
- Failed to start Hyperliquid task generation: {e}
- Failed to start Hyperliquid execution session generation: {e
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/f2bb46d0f4de5435.
Report an issue: GitHub.