nautechsystems/nautilus_trader · error
Failed to start Derive data session generation: {e}
Error message
Failed to start Derive data session generation: {e} What it means
During the Derive data client's `connect`, if the session/pending task groups are not in a clean state, it tears down partial state and starts a new generation for `session_tasks`. This error wraps a failure of that generation start, blocking the data client from establishing its WebSocket session task set.
Source
Thrown at crates/adapters/derive/src/data.rs:745
async fn connect(&mut self) -> anyhow::Result<()> {
if self.is_connected()
&& !self.cancellation_token.is_cancelled()
&& self.session_tasks.is_open()
&& self.pending_tasks.is_open()
{
return Ok(());
}
// Completes the async teardown deferred by sync reset()/stop().
if self.cancellation_token.is_cancelled()
|| !self.session_tasks.is_open()
|| !self.pending_tasks.is_open()
{
self.teardown_partial_connect().await?;
self.cancellation_token = CancellationToken::new();
self.session_tasks.start_generation().map_err(|e| {
anyhow::anyhow!("Failed to start Derive data session generation: {e}")
})?;
self.pending_tasks
.start_generation()
.map_err(|e| anyhow::anyhow!("Failed to start Derive data task generation: {e}"))?;
}
let cancellation_token = self.cancellation_token.clone();
let ws_shutdown = self.ws_client.shutdown_handle();
let setup_guard =
TaskGroupGuard::new(&[&self.session_tasks, &self.pending_tasks], move || {
cancellation_token.cancel();
ws_shutdown.begin_shutdown();
});
if !self.config.currencies.is_empty() {
self.provider
.load_all(None)
.await
.context("failed to load Derive instruments")?;View on GitHub (pinned to 18893faf8b)
Solutions
- Read the wrapped `{e}` from start_generation for the root cause.
- Await full teardown (`teardown_partial_connect`) / prior disconnect before reconnecting.
- Avoid concurrent connect() calls on the same data client; serialize lifecycle calls.
- Recreate the data client if its task groups were permanently shut down.
- Check that the tokio runtime isn't being dropped mid-connect.
Example fix
// before data_client.connect().await?; // after a failed earlier connect // after data_client.disconnect().await?; // ensure clean state data_client.connect().await?;
Defensive patterns
Strategy: retry
Validate before calling
// Only connect when previous lifecycle ended:
if !data_client.is_connected() && prior_connect_finished { data_client.connect().await?; } Try / catch
match data_client.connect().await {
Err(e) if e.to_string().contains("session generation") => {
tokio::time::sleep(BACKOFF).await;
data_client.connect().await.context("reconnect failed")?;
}
other => other?,
} Prevention
- Ensure disconnect/teardown completes before reconnecting.
- Use a single supervisor task to own connect/disconnect.
- Add retry with exponential backoff.
- Watch for runtime shutdown racing connection setup.
When it happens
Trigger: Calling `connect()` on the Derive data client when `session_tasks` is not open/empty and `start_generation()` returns Err (group shut down, generation state invalid, prior teardown incomplete).
Common situations: Reconnecting after an aborted connect whose teardown didn't fully complete; concurrent connect attempts on the same data client; runtime shutdown racing connection setup.
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 Derive data task generation: {e}
- failed to start WebSocket handler task generation: {e}
- Derive WebSocket event receiver not initialized
- joined shutdown errors (std::mem::take(&mut self.shutdown_er
- invalid Derive subscription channel `{channel}`
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/fd66b93394f45b58.
Report an issue: GitHub.