nautechsystems/nautilus_trader · error · anyhow::Error
Failed to start Hyperliquid data task generation: {e}
Error message
Failed to start Hyperliquid data task generation: {e} What it means
Same connect sequence as error 3102 but for the `pending_tasks` manager: `pending_tasks.start_generation()` failed while starting a new generation of background (pending) data tasks. Connect aborts with this error after the session generation already started, leaving the client not fully connected.
Source
Thrown at crates/adapters/hyperliquid/src/data.rs:643
// task so its receiver and subscription registries cannot belong
// to the previous generation.
self.ws_client.begin_shutdown();
self.ws_client
.disconnect()
.await
.context("failed to tear down Hyperliquid WebSocket before reconnect")?;
self.ws_client.reset_runtime_state();
self.abort_session_tasks();
self.abort_pending_tasks();
let (session_result, pending_result) =
tokio::join!(self.await_session_tasks(), self.await_pending_tasks());
session_result?;
pending_result?;
self.session_tasks.start_generation().map_err(|e| {
anyhow::anyhow!("Failed to start Hyperliquid data session generation: {e}")
})?;
self.pending_tasks.start_generation().map_err(|e| {
anyhow::anyhow!("Failed to start Hyperliquid data task generation: {e}")
})?;
self.cancellation_token = CancellationToken::new();
}
let cancellation_token = self.cancellation_token.clone();
let ws_client = self.ws_client.clone();
let setup_guard =
TaskGroupGuard::new(&[&self.session_tasks, &self.pending_tasks], move || {
cancellation_token.cancel();
ws_client.begin_shutdown();
});
register_hyperliquid_custom_data();
let instruments = self
.bootstrap_instruments()
.await
.context("failed to bootstrap instruments")?;
View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure full teardown before reconnecting (await disconnect to completion).
- Serialize the connect/disconnect lifecycle; never interleave them.
- Recreate the data client if the task manager remains in a bad state.
- Check logs for the earlier pending-task shutdown error that left the stale state.
Example fix
// before let _ = client.disconnect().await; // ignoring incomplete teardown client.connect().await?; // after client.disconnect().await?; // propagate teardown errors first client.connect().await?;
Defensive patterns
Strategy: try-catch
Try / catch
// serialize lifecycle; on pending-generation failure, tear down and retry once
if let Err(e) = client.connect().await {
if e.to_string().contains("task generation") {
let _ = client.disconnect().await;
tokio::time::sleep(Duration::from_millis(500)).await;
client.connect().await?;
} else {
return Err(e);
}
} Prevention
- Do not interleave connect/disconnect calls; run them sequentially in one owner task.
- Handle earlier pending-task shutdown errors instead of ignoring disconnect results.
- Use a fresh client instance if task-manager state appears corrupted.
When it happens
Trigger: Calling connect when the pending-task registry cannot start a new generation — stale generation state from an incomplete previous shutdown, or concurrent connect/teardown racing on the same client.
Common situations: Rapid reconnect loops in a supervisor; calling connect while a previous disconnect's `await_pending_tasks` was still timing out; sharing one client across tasks.
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 Hyperliquid data session generation: {e}
- RTDS task owner was dropped
- Failed to terminate Hyperliquid data session tasks: {e}
- No WebSocket client available
- std::mem::take(&mut self.shutdown_errors).join("; ")
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/fe810839f81f9b65.
Report an issue: GitHub.