{"record":{"id":"5ee3ffa6fee5db68","repo":"nautechsystems/nautilus_trader","slug":"failed-to-terminate-lighter-tasks","errorCode":null,"errorMessage":"Failed to terminate Lighter tasks: {}","messagePattern":"Failed to terminate Lighter tasks: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/execution.rs","lineNumber":479,"sourceCode":"        )\n        .await;\n\n        if let Err(e) = self\n            .pending_tasks\n            .finish_shutdown(Duration::from_secs(1), DISCONNECT_TIMEOUT)\n            .await\n        {\n            self.shutdown_errors\n                .push(format!(\"client-owned tasks failed: {e}\"));\n        }\n\n        let stale = self.dispatch.take_pending_sendtx();\n        warn_pending_sendtx_unknown(&stale, \"session shutdown\");\n        self.nonce_recovery_inflight.store(false, Ordering::Release);\n\n        if !self.shutdown_errors.is_empty() {\n            let errors = std::mem::take(&mut self.shutdown_errors);\n            anyhow::bail!(\"Failed to terminate Lighter tasks: {}\", errors.join(\"; \"));\n        }\n        Ok(())\n    }\n\n    async fn finish_owned_task(\n        slot: &mut TaskSlot<()>,\n        description: &str,\n        errors: &mut Vec<String>,\n    ) {\n        let Some(outcome) = finish_task(slot, DISCONNECT_TIMEOUT, DISCONNECT_TIMEOUT).await else {\n            return;\n        };\n\n        match outcome {\n            TaskJoinOutcome::Completed(()) => {\n                log::debug!(\"Lighter {description} task completed\");\n            }\n            TaskJoinOutcome::Aborted => {","sourceCodeStart":461,"sourceCodeEnd":497,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/execution.rs#L461-L497","documentation":"Aggregated shutdown-failure error from the Lighter execution client. finish_session_shutdown (invoked by connect on failure and by disconnect) drains shutdown_errors accumulated from finishing owned tasks (WS senders, writers, nonce manager, etc.); if any are present it bails with this message and the joined per-task errors. It signals the execution session's background tasks did not all terminate cleanly.","triggerScenarios":"Calling disconnect() on the Lighter execution client (or connect() aborting partway) while one or more owned tasks returned an error on completion - e.g. WS send channel already closed, writer task failed on a broken transport, or a task panicked.","commonSituations":"Disconnecting while an order submission is in flight and the writer task errors; network outage during teardown; repeated reconnect cycles leaving errored task handles; nonce manager task failing during shutdown.","solutions":["Inspect the joined error text after the prefix to identify which task failed and why.","Retry disconnect(); teardown errors during an outage typically resolve once connectivity is restored and usually don't affect already-submitted orders.","Check connectivity/proxy stability if this fires on every shutdown.","If shutdown consistently reports errors on a healthy connection, capture the full message and file a bug with the task description listed in it."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match exec_client.disconnect().await {\n    Ok(()) => {}\n    Err(e) if e.to_string().starts_with(\"Failed to terminate Lighter tasks\") => {\n        tracing::warn!(\"execution teardown errors: {e:#}\");\n        // parse joined task errors; retry disconnect if network was down\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Avoid disconnecting while orders are in flight; await order terminal states first.","Retry disconnect after transient network failures.","Log and inspect the joined task errors to find the failing background task."],"tags":["rust","execution","websocket","shutdown","task-management"],"backgroundTag":"task-shutdown-failed","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"}