nautechsystems/nautilus_trader · error
errors.join("; ")
Error message
errors.join("; ") What it means
During teardown of the Bybit data client, finish_tasks joins session and command tasks; any task that fails to finish is collected as a message. If any errors accumulated, the whole operation bails with all messages joined by "; ". This indicates background websocket/HTTP tasks did not shut down cleanly during connect/teardown.
Source
Thrown at crates/adapters/bybit/src/data.rs:264
let (session_result, command_result) = tokio::join!(
self.session_tasks
.finish_shutdown(Duration::from_secs(1), Duration::from_secs(2)),
self.command_tasks
.finish_shutdown(Duration::from_secs(1), Duration::from_secs(2)),
);
let mut errors = Vec::new();
if let Err(e) = session_result {
errors.push(format!("failed to finish Bybit data session tasks: {e}"));
}
if let Err(e) = command_result {
errors.push(format!("failed to finish Bybit data command tasks: {e}"));
}
if errors.is_empty() {
Ok(())
} else {
anyhow::bail!(errors.join("; "))
}
}
async fn prepare_task_groups(&mut self) -> anyhow::Result<()> {
if !self.session_tasks.is_open() || !self.command_tasks.is_open() {
self.teardown_partial_connect().await?;
self.session_tasks
.start_generation()
.context("failed to start Bybit data session task generation")?;
self.command_tasks
.start_generation()
.context("failed to start Bybit data command task generation")?;
self.cancellation_token = self.session_tasks.cancellation_token();
}
Ok(())
}
fn spawn_ws<F>(&self, fut: F, context: &'static str)View on GitHub (pinned to 18893faf8b)
Solutions
- Read the joined messages to identify which tasks failed and the root cause
- Check network/proxy stability and Bybit exchange status
- Retry the connection after the failed teardown
- If persistent, capture logs and file an issue with the specific task error
Defensive patterns
Strategy: try-catch
Validate before calling
// before connect: check connectivity to Bybit endpoints
async fn bybit_reachable() -> bool { reqwest::get("https://api.bybit.com/v5/market/time").await.is_ok() } Try / catch
match client.connect().await {
Ok(()) => {},
Err(e) => {
log::error!("Bybit data connect/teardown failed: {e:#}");
tokio::time::sleep(BACKOFF).await;
retry_connect();
}
} Prevention
- Ensure stable network/proxy before connecting
- Monitor Bybit status during startup
- Treat the joined message list as the diagnostic — read every task error
- Add exponential backoff on connect retries
When it happens
Trigger: Calling connect (via prepare_task_groups -> teardown_partial_connect) or disconnect when one or more spawned data command tasks returned an error like "failed to finish Bybit data command tasks: ...".
Common situations: Network drops mid-connect leaving tasks in a bad state; exchange websocket closing unexpectedly during startup/shutdown; partial connect failures where some tasks already errored.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- Bybit execution shutdown failed: {}
- Failed to terminate Bybit execution session tasks: {e}
- failed to finish Binance Futures data command tasks: {e}
- Binance Futures data teardown failed: {}
- Binance Futures shutdown failed: {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/246feeaa5a0003ac.
Report an issue: GitHub.