nautechsystems/nautilus_trader · error
Failed to send WebSocket client to handler: {e}
Error message
Failed to send WebSocket client to handler: {e} What it means
After spawning the handler task, `connect` must register the newly created WebSocket client with it by sending `HandlerCommand::SetClient` over the command channel. If that send fails, the client initiates an emergency handler shutdown; this error reports the send failure, and if the shutdown itself also failed, the message is extended with the shutdown error.
Source
Thrown at crates/adapters/okx/src/websocket/client.rs:866
if let Err(e) = handler_spawner.spawn(handler_task) {
self.out_rx = None;
anyhow::bail!("Failed to register WebSocket handler task: {e}");
}
let set_client_result = {
let cmd_tx = self.cmd_tx.read().await;
cmd_tx.send(HandlerCommand::SetClient(client))
};
if let Err(e) = set_client_result {
self.handler_tasks.begin_shutdown();
self.signal.store(true, Ordering::Release);
let handler_abort = self.handler_abort.lock().clone();
handler_abort.cancel();
let shutdown_result = self.close_stream_task(Duration::from_secs(2)).await;
self.out_rx = None;
anyhow::bail!(match shutdown_result {
Ok(()) => format!("Failed to send WebSocket client to handler: {e}"),
Err(shutdown_error) => format!(
"Failed to send WebSocket client to handler: {e}; handler shutdown failed: \
{shutdown_error}"
),
});
}
if let Some(control) = &self.socket_control {
control.register(move || reconnect_handle.request_reconnect());
}
log::debug!("Sent WebSocket client to handler");
if self.credential.is_some()
&& let Err(e) = self.authenticate().await
{
self.handler_tasks.begin_shutdown();
self.request_close().await;View on GitHub (pinned to 18893faf8b)
Solutions
- Check for an earlier handler-task panic (look for panic logs just before this error).
- Retry `connect()` after ensuring `disconnect()` completed cleanly.
- Examine the appended `handler shutdown failed` text if present — resolve that shutdown error as well before reconnecting.
Defensive patterns
Strategy: retry
Try / catch
// this error means the handler died mid-connect; recreate and retry with backoff
match client.connect().await {
Err(e) if e.to_string().contains("Failed to send WebSocket client to handler") => {
tokio::time::sleep(Duration::from_secs(1)).await;
client = build_new_client()?; // internal channel state was rolled back
client.connect().await?;
}
other => other?,
} Prevention
- Investigate any handler-task panics logged just before this error.
- Serialize connect/disconnect calls so teardown never races connect.
- Recreate the client after this error; the command channel was dropped.
When it happens
Trigger: `cmd_tx.send(HandlerCommand::SetClient(client))` fails during `connect()` — typically because the handler task's command receiver was dropped (handler died immediately after spawn).
Common situations: Handler task panicked or aborted right after spawn; runtime shutdown racing the connection; preceding spawn errors leaving the channel broken.
Related errors
- Authentication failed: {e}
- Bybit data shutdown failed: {}
- Failed to send SetClient command: {e}
- unsupported Derive public WS channel `{}`
- Failed to send SetClient command: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/a07c6535966a203b.
Report an issue: GitHub.