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

  1. Check for an earlier handler-task panic (look for panic logs just before this error).
  2. Retry `connect()` after ensuring `disconnect()` completed cleanly.
  3. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/a07c6535966a203b. Report an issue: GitHub.