nautechsystems/nautilus_trader · error
Failed to start Lighter task generation: {e}
Error message
Failed to start Lighter task generation: {e} What it means
During Lighter connection setup, after finishing any prior session shutdown, the client starts task generation on pending_tasks (a task group). If start_generation() returns an error, it is wrapped in this anyhow error and connection setup aborts. This means the client's internal task scheduler could not begin producing background tasks for the new connection session.
Source
Thrown at crates/adapters/lighter/src/execution.rs:4066
);
}
log::info!(
"Connecting Lighter execution client {}",
self.core.client_id
);
// Synchronous stop/reset can only initiate teardown. Complete it before
// publishing a replacement socket or sharing its connection epoch.
if !self.session_tasks_finished() || !self.pending_tasks.is_open() {
self.begin_session_shutdown();
self.finish_session_shutdown().await?;
}
if !self.pending_tasks.is_open() {
self.pending_tasks
.start_generation()
.map_err(|e| anyhow::anyhow!("Failed to start Lighter task generation: {e}"))?;
self.cancellation_token = self.pending_tasks.cancellation_token();
}
let ws_client = self.ws_client.clone();
let setup_guard = TaskGroupGuard::new(&[&self.pending_tasks], move || {
ws_client.begin_shutdown();
});
self.auth_refresh_notify = Arc::new(tokio::sync::Notify::new());
// Reset the readiness gate and clear derived position/account caches
// so a prior session's state cannot leak past the strict-await gate.
// The Reconnected path (WS-layer transparent reconnect) is unaffected:
// it does not re-enter `connect()`. Its next `account_all_positions`
// frame replaces the position cache through the consumption loop.
self.dispatch.account_streams_ready.reset();
self.dispatch.clear_position_cache();
self.dispatch.clear_account_state_cache();
View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the previous connection's shutdown fully completed before reconnecting (await disconnect/shutdown before connect)
- Avoid concurrent connect() calls on the same client instance; serialize connections
- If the group is permanently wedged, rebuild/recreate the execution client instead of reusing it
Example fix
// before self.client.connect().await?; // after self.client.disconnect().await?; self.client.connect().await?;
Defensive patterns
Strategy: try-catch
Validate before calling
if client.is_connected() || client.is_shutting_down() {
return Err(anyhow!("client busy"));
} Try / catch
match client.connect().await {
Err(e) if e.to_string().contains("task generation") => {
// recreate or retry after full shutdown
}
other => other?,
} Prevention
- Always await full disconnect before reconnecting
- Never call connect concurrently on one client
- Recreate the client after repeated start_generation failures
When it happens
Trigger: Calling connect/connect_async when the task group's generation counter cannot advance — e.g. the group was already shut down and not reset, or its internal state (token/generation) is in a conflicting state from a previous failed shutdown.
Common situations: Rapid reconnect loops where a previous session shutdown raced the new start; cancellation token leaked from a cancelled prior session; calling connect twice concurrently on the same client.
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 data command tasks: {e}
- Failed to start AX execution session generation: {e}
- Failed to start Betfair session generation: {e}
- Failed to start Betfair task generation: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/dc8c3d3b381c0c12.
Report an issue: GitHub.