nautechsystems/nautilus_trader · error
Failed to start Betfair task generation: {e}
Error message
Failed to start Betfair task generation: {e} What it means
Immediately after starting the session generation, connect starts the pending_tasks generation for order/account requests. If start_generation fails, teardown_partial_connect runs and the error is wrapped with this message.
Source
Thrown at crates/adapters/betfair/src/execution.rs:1451
self.clear_resync_state();
log::info!("Stopped: client_id={}", self.core.client_id);
Ok(())
}
async fn connect(&mut self) -> anyhow::Result<()> {
if self.core.is_connected() && self.session_tasks.is_open() && self.pending_tasks.is_open()
{
return Ok(());
}
if !self.session_tasks.is_open() || !self.pending_tasks.is_open() {
self.teardown_partial_connect().await?;
self.session_tasks
.start_generation()
.map_err(|e| anyhow::anyhow!("Failed to start Betfair session generation: {e}"))?;
self.pending_tasks
.start_generation()
.map_err(|e| anyhow::anyhow!("Failed to start Betfair task generation: {e}"))?;
}
let http_cancellation = self.http_client.cancellation_token();
let setup_guard =
TaskGroupGuard::new(&[&self.session_tasks, &self.pending_tasks], move || {
http_cancellation.cancel();
});
register_betfair_custom_data();
let session_token_result = async {
self.http_client
.connect()
.await
.map_err(|e| anyhow::anyhow!("{e}"))?;
let funds: AccountFundsResponse = self
.http_clientView on GitHub (pinned to 18893faf8b)
Solutions
- Serialize connect/disconnect calls
- Await completion of any previous teardown before reconnecting
- Log the inner `e` to identify whether the group was closed or already open
Example fix
// before: racing reconnect with shutdown disconnect_future.abort(); client.connect().await?; // after: await teardown first disconnect_future.await.ok(); client.connect().await?;
Defensive patterns
Strategy: validation
Validate before calling
if client.is_connected() { return Ok(()); } Type guard
fn can_connect(client: &BetfairExecClient) -> bool {
!client.is_connected() && !client.is_shutting_down()
} Try / catch
if let Err(e) = client.connect().await {
if e.to_string().contains("task generation") {
client.disconnect().await.ok();
client.connect().await?;
} else { return Err(e); }
} Prevention
- Serialize lifecycle transitions
- Let the setup guard (TaskGroupGuard) complete before shutdown
- Treat connect as idempotent-guarded in your wrapper
When it happens
Trigger: pending_tasks group not in a startable state — concurrent connects, prior shutdown still in progress, or session generation started but pending generation refused.
Common situations: Same lifecycle races as session generation: double connect, reconnect during teardown, half-initialized client after a failed connect.
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 session generation: {e}
- Failed to start Betfair data session tasks: {e}
- Failed to start Betfair data command tasks: {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/6e8d6fe2ec020f98.
Report an issue: GitHub.