nautechsystems/nautilus_trader · error
failed to start WebSocket handler task generation: {e}
Error message
failed to start WebSocket handler task generation: {e} What it means
After stopping prior handler tasks during `connect()`, the client advances `handler_tasks` to a new generation via `start_generation()`. This error wraps a failure of that generation rollover, meaning the client cannot prepare a fresh task-generation for the new WebSocket session.
Source
Thrown at crates/adapters/deribit/src/websocket/client.rs:537
/// Returns an error if the connection fails.
pub async fn connect(&mut self) -> anyhow::Result<()> {
let connect_lock = Arc::clone(&self.connect_lock);
let _connect_guard = connect_lock.lock().await;
log_debug!(
"Connecting to WebSocket: {}",
self.url,
color = LogColor::Blue
);
if !self.handler_tasks.is_open() || !self.handler_tasks.is_empty() {
self.handler_tasks.begin_shutdown();
self.signal.store(true, Ordering::Relaxed);
self.finish_handler()
.await
.map_err(|e| anyhow::anyhow!("failed to stop prior WebSocket handler: {e}"))?;
self.handler_tasks.start_generation().map_err(|e| {
anyhow::anyhow!("failed to start WebSocket handler task generation: {e}")
})?;
}
let handler_spawner = self.handler_tasks.spawner().map_err(|e| {
anyhow::anyhow!("failed to acquire WebSocket handler task spawner: {e}")
})?;
// Reset stop signal and subscription state so callers can
// resubscribe cleanly after a manual disconnect/connect cycle.
self.signal.store(false, Ordering::Relaxed);
self.subscriptions_state.clear();
// Create message handler and channel
let (message_handler, raw_rx) = channel_message_handler();
// No-op ping handler: handler responds to pings directly
// Inbound Ping frames are answered by the transport, so no ping handler is needed;
// the reader routes them away from the message channel and the handler never sees them.
View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the wrapped `{e}` from start_generation for the specific generation-state reason.
- Wait for full teardown of the previous session (await disconnect) before reconnecting.
- Serialize connect calls; add a mutex/actor around connect/disconnect.
- If the task group was permanently shut down, rebuild a new client instance instead of reconnecting.
- File/inspect TaskGroup logic if start_generation fails on a fresh open group.
Example fix
// before client.connect().await?; // may race old generation teardown // after tokio::time::sleep(Duration::from_millis(100)).await; // or await disconnect completion client.connect().await?;
Defensive patterns
Strategy: try-catch
Validate before calling
// Track session lifecycle yourself; only connect when fully disconnected. assert!(client.is_disconnected());
Try / catch
if let Err(e) = client.connect().await {
if e.to_string().contains("handler task generation") {
tokio::time::sleep(RECONNECT_DELAY).await;
client = rebuild_client().await?;
}
} Prevention
- Await previous disconnect completion before connect.
- Use bounded retry with backoff on reconnect loops.
- Avoid sharing one client across concurrent tasks without a mutex.
- Recreate the client after repeated generation errors.
When it happens
Trigger: Calling `connect()` after prior handlers exist and `handler_tasks.start_generation()` returns an Err — e.g. the generation manager still considers a prior generation active, or it was shut down and cannot restart.
Common situations: Rapid disconnect/reconnect cycles racing the previous generation's teardown; a prior `finish_handler()` that only partially completed; shutting down the task group while a reconnect is in flight.
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 session generation: {e}
- Failed to start Derive data task generation: {e}
- Failed to start Coinbase session generation: {e}
- failed to stop prior WebSocket handler: {e}
- failed to acquire WebSocket handler task spawner: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d883ebf34b565fd0.
Report an issue: GitHub.