nautechsystems/nautilus_trader · error
failed to acquire WebSocket handler task spawner: {e}
Error message
failed to acquire WebSocket handler task spawner: {e} What it means
`connect()` obtains a spawner from `handler_tasks` to launch the new WebSocket handler tasks. This error is thrown when the spawner cannot be acquired, meaning the task group is in a state (shut down, mid-generation) where spawning is not allowed.
Source
Thrown at crates/adapters/deribit/src/websocket/client.rs:541
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.
// Configure WebSocket client
let config = WebSocketConfig {
url: self.url.clone(),
headers: vec![(USER_AGENT.to_string(), NAUTILUS_USER_AGENT.to_string())],View on GitHub (pinned to 18893faf8b)
Solutions
- Check the wrapped `{e}` to confirm the task-group state (closed vs wrong generation).
- Create a fresh Deribit WebSocket client instead of reusing a shut-down one.
- Avoid calling connect after shutdown/close of the client.
- Serialize connect calls to prevent two setups from racing generation state.
- If you need repeated reconnects, verify each prior disconnect completed cleanly first.
Example fix
// before let client = DeribitWsClient::new(...); client.disconnect().await?; client.connect().await?; // fails if internal tasks shut down // after let client = DeribitWsClient::new(...); // fresh client per lifecycle client.connect().await?;
Defensive patterns
Strategy: try-catch
Validate before calling
// Only reuse a client within its valid lifecycle; do not connect after shutdown.
if client_is_shutdown { client = DeribitWsClient::new(...)?; } Try / catch
match client.connect().await {
Err(e) if e.to_string().contains("handler task spawner") => {
let mut client = DeribitWsClient::new(config).await?;
client.connect().await?;
}
other => other?,
} Prevention
- Never call connect after shutdown/close.
- Treat the client as single-lifecycle; rebuild for a fresh session.
- Guard connect entry points against concurrent invocation.
- Keep reconnect logic inside a dedicated supervisor task.
When it happens
Trigger: Any call to `connect()` where `handler_tasks.spawner()` returns Err — typically the group was shut down, closed, or is in an invalid generation state after prior start_generation calls.
Common situations: Reusing a client after an explicit shutdown/close; connect invoked while another connect is mid-setup; the client was dropped from a task set that has ended its lifecycle.
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 Spot public JSON WS bytes task: {e}
- Failed to start Spot public JSON WS handler task: {e}
- failed to register WebSocket handler task: {e}
- Failed to start Hyperliquid WebSocket handler task: {e}
- Failed to register WebSocket handler task: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/3c1ee9307da26411.
Report an issue: GitHub.