{"record":{"id":"682281ad3c4df7d7","repo":"nautechsystems/nautilus_trader","slug":"failed-to-terminate-bybit-execution-tasks-e","errorCode":null,"errorMessage":"Failed to terminate Bybit execution tasks: {e}","messagePattern":"Failed to terminate Bybit execution tasks: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/execution.rs","lineNumber":269,"sourceCode":"        if let Err(e) = self.pending_tasks.spawn(future) {\n            log::warn!(\"Skipping Bybit {description} after shutdown began: {e}\");\n        }\n    }\n\n    fn abort_pending_tasks(&self) {\n        self.pending_tasks.begin_shutdown();\n    }\n\n    fn abort_session_tasks(&self) {\n        self.session_tasks.begin_shutdown();\n    }\n\n    async fn await_pending_tasks(&self) -> anyhow::Result<()> {\n        self.pending_tasks.begin_shutdown();\n        self.pending_tasks\n            .finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to terminate Bybit execution tasks: {e}\"))?;\n        Ok(())\n    }\n\n    async fn await_session_tasks(&self) -> anyhow::Result<()> {\n        self.session_tasks.begin_shutdown();\n        self.session_tasks\n            .finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))\n            .await\n            .map_err(|e| {\n                anyhow::anyhow!(\"Failed to terminate Bybit execution session tasks: {e}\")\n            })?;\n        Ok(())\n    }\n\n    async fn teardown_partial_connect(&mut self) -> anyhow::Result<()> {\n        self.abort_session_tasks();\n        self.abort_pending_tasks();\n        self.http_client.cancel_all_requests();","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/execution.rs#L251-L287","documentation":"During shutdown, BybitExecutionClient awaits its background (pending) tasks to terminate via finish_shutdown with tight timeouts (1s begin, 2s finish). If tasks do not stop in time or the task group reports an error, the client wraps it in this anyhow error so callers of teardown/connect see shutdown failure explicitly.","triggerScenarios":"Calling disconnect/teardown_partial_connect while a pending task (e.g. order update stream) is blocked or slow, exceeding the 1–2 second shutdown windows.","commonSituations":"Network stalls, deadlocked callbacks, or long-running handlers preventing task cancellation; also flaky teardown during reconnect cycles.","solutions":["Retry the disconnect; transient task termination often succeeds on a second attempt","Check task handlers for blocking calls that prevent cancellation","Inspect the inner error {e} for whether it was a timeout vs an explicit abort","Report/persist the error since some tasks may linger until process exit"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Before teardown, ensure no pending callbacks are mid-await:\n// e.g. wait for in-flight order update handlers to drain before disconnect.","typeGuard":null,"tryCatchPattern":"if let Err(e) = client.disconnect().await {\n    if e.to_string().contains(\"Failed to terminate Bybit execution tasks\") {\n        tracing::warn!(\"shutdown timed out: {e}; retrying once\");\n        tokio::time::sleep(Duration::from_millis(500)).await;\n        let _ = client.disconnect().await;\n    } else {\n        return Err(e);\n    }\n}","preventionTips":["Avoid blocking calls inside task handlers","Disconnect on the same runtime that spawned the client","Monitor logs for slow handlers during shutdown"],"tags":["bybit","shutdown","async","timeout"],"backgroundTag":"request-timeout","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"}