{"record":{"id":"86031f5a63441ea0","repo":"nautechsystems/nautilus_trader","slug":"ws-handler-command-sender-unavailable","errorCode":null,"errorMessage":"WS handler command sender unavailable","messagePattern":"WS handler command sender unavailable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/kraken/src/websocket/dispatch/spot_orders.rs","lineNumber":262,"sourceCode":"\n    fn send(\n        self: &Arc<Self>,\n        mut envelope: KrakenWsRequest,\n        mut identity: PendingRequest,\n        ts_now_ns: u64,\n    ) -> anyhow::Result<u64> {\n        let req_id = self.next_req_id();\n        envelope.req_id = Some(req_id);\n        identity.ts_sent_ns = ts_now_ns;\n\n        let payload = SecretString::from(\n            serde_json::to_string(&envelope)\n                .map_err(|e| anyhow::anyhow!(\"serialize WS order request: {e}\"))?,\n        );\n\n        let cmd_tx = self\n            .cmd_tx()\n            .ok_or_else(|| anyhow::anyhow!(\"WS handler command sender unavailable\"))?;\n\n        self.pending.insert(req_id, identity);\n\n        if let Err(e) = cmd_tx.send(SpotHandlerCommand::SendOrderRequest { req_id, payload }) {\n            self.pending.remove(&req_id);\n            anyhow::bail!(\"handler command channel closed: {e}\");\n        }\n\n        let state_for_timeout = Arc::downgrade(self);\n        let task_spawner = self.task_spawner.read().clone();\n        let cancel = task_spawner.cancellation_token();\n        let timeout = self.timeout;\n\n        if let Err(e) = task_spawner.spawn(async move {\n            tokio::select! {\n                biased;\n                () = cancel.cancelled() => {\n                    if let Some(state) = state_for_timeout.upgrade() {","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/kraken/src/websocket/dispatch/spot_orders.rs#L244-L280","documentation":"The Kraken spot orders dispatcher has no command sender (`cmd_tx`) available, so it cannot forward the serialized order request to the WebSocket handler task. `cmd_tx()` returns None when the WS handler command channel has not been established (e.g. not connected) or has been dropped. The order is aborted before being inserted into `pending`.","triggerScenarios":"Calling `send` on the spot orders dispatcher before the WebSocket connection/handler is started, or after the handler task has shut down and dropped the receiving end of the command channel.","commonSituations":"Submitting an order during adapter startup before the WS client is fully connected; orders submitted after a disconnect or shutdown of the WS handler; lifecycle races where the account/executor is live while the WS handler is not.","solutions":["Ensure the Kraken WebSocket client/handler is started and connected before submitting orders.","Check adapter logs for prior disconnect/shutdown events and re-establish the WS connection.","Add connection-state checks or retry logic so orders are only sent when the WS handler is live.","If the handler task panicked or exited, inspect its logs and restart the adapter/client."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Only send when the WS handler is connected\nif !ws_client.is_connected() { log::warn!(\"Kraken WS not connected; skipping order send\"); return; }","typeGuard":"fn has_cmd_tx(dispatcher: &SpotOrdersDispatcher) -> bool {\n    dispatcher.cmd_tx().is_some()\n}","tryCatchPattern":"match dispatcher.send(order) {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"command sender unavailable\") => reconnect_and_resubmit(),\n    Err(e) => log::error!(\"order send failed: {e}\"),\n}","preventionTips":["Gate order submission on WS connection state.","Monitor adapter disconnect events and pause trading until reconnected.","Ensure the WS handler task is started before the execution engine."],"tags":["websocket","channel","lifecycle","kraken"],"backgroundTag":"resource-not-found","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}