{"record":{"id":"e1d49a574bf7f426","repo":"nautechsystems/nautilus_trader","slug":"bybit-data-shutdown-failed","errorCode":null,"errorMessage":"Bybit data shutdown failed: {}","messagePattern":"Bybit data shutdown failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/data.rs","lineNumber":422,"sourceCode":"            ws_client.begin_shutdown();\n        }\n\n        for ws_client in &mut self.ws_clients {\n            if let Err(e) = ws_client.close().await {\n                self.shutdown_errors.push(e.to_string());\n            }\n        }\n\n        if let Err(e) = self.finish_tasks().await {\n            self.shutdown_errors.push(e.to_string());\n        }\n        self.is_connected.store(false, Ordering::Release);\n\n        if self.shutdown_errors.is_empty() {\n            Ok(())\n        } else {\n            let errors = std::mem::take(&mut self.shutdown_errors);\n            anyhow::bail!(\"Bybit data shutdown failed: {}\", errors.join(\"; \"))\n        }\n    }\n}\n\nfn send_data(sender: &tokio::sync::mpsc::UnboundedSender<DataEvent>, data: Data) {\n    if let Err(e) = sender.send(DataEvent::Data(data)) {\n        log::error!(\"Failed to emit data event: {e}\");\n    }\n}\n\nfn validate_orderbook_depth(depth: u32) -> anyhow::Result<()> {\n    if !BYBIT_BOOK_DEPTHS.contains(&depth) {\n        anyhow::bail!(\"invalid depth {depth}; valid values are {BYBIT_BOOK_DEPTHS:?}\");\n    }\n\n    Ok(())\n}\n","sourceCodeStart":404,"sourceCodeEnd":440,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/data.rs#L404-L440","documentation":"teardown_partial_connect rolls back a partially completed Bybit data client connect: it stops tasks, closes sessions, and collects shutdown_errors. If any errors occurred while tearing down, it bails with all of them joined. This surfaces secondary failures that occurred while recovering from a failed connect.","triggerScenarios":"A connect attempt fails partway (e.g. session or command task startup fails) and cleanup itself encounters errors — such as failing to abort tasks or close websocket sessions — producing non-empty shutdown_errors.","commonSituations":"Unstable network during connect causing both startup failure and messy cleanup; exchange refusing connections so multiple subsystems error during rollback; calling connect repeatedly during an outage.","solutions":["Fix the primary connect failure first (network, API credentials, region blocking)","Check Bybit status and connectivity before retrying","Retry connect after backoff; shutdown_errors are drained so a clean retry is safe","If cleanup errors persist on a healthy network, report with full logs"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// pre-flight: verify API reachability and credentials before connect\nassert!(bybit_reachable().await, \"Bybit API unreachable\");","typeGuard":null,"tryCatchPattern":"loop {\n    match client.connect().await {\n        Ok(()) => break,\n        Err(e) if attempts < MAX => { log::warn!(\"retrying after partial teardown: {e:#}\"); attempts += 1; backoff(); }\n        Err(e) => return Err(e),\n    }\n}","preventionTips":["Fix the root connect failure first; teardown errors are secondary","Drain-and-retry is safe: shutdown_errors are reset via mem::take","Avoid hammering connect during exchange outages — use backoff","Check region/IP restrictions that cause repeated partial failures"],"tags":["bybit","connect","teardown","websocket"],"backgroundTag":"connection-refused","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}