nautechsystems/nautilus_trader · error
joined shutdown errors (std::mem::take(&mut self.shutdown_er
Error message
joined shutdown errors (std::mem::take(&mut self.shutdown_errors).join("; ")) What it means
Raised by `teardown_partial_connect` in the Derive data client when one or more pending connection tasks failed during teardown. Each failure string is accumulated in `shutdown_errors`, then all errors are joined with "; " and returned as a single aggregated error once the teardown completes.
Source
Thrown at crates/adapters/derive/src/data.rs:271
self.shutdown_errors
.push(format!("Derive WebSocket shutdown failed: {e}"));
}
let (session_result, pending_result) =
tokio::join!(self.join_session_tasks(), self.join_pending_tasks());
self.clear_subscription_state();
self.channel_subscriptions.clear_transitions();
self.is_connected.store(false, Ordering::Release);
if let Err(e) = session_result {
self.shutdown_errors.push(e.to_string());
}
if let Err(e) = pending_result {
self.shutdown_errors.push(e.to_string());
}
if !self.shutdown_errors.is_empty() {
anyhow::bail!(std::mem::take(&mut self.shutdown_errors).join("; "));
}
Ok(())
}
fn spawn_stream_task(
&self,
mut rx: tokio::sync::mpsc::UnboundedReceiver<DeriveWsMessage>,
) -> anyhow::Result<()> {
let ctx = WsMessageContext {
clock: self.clock,
data_sender: self.data_sender.clone(),
instruments: Arc::clone(&self.instruments),
active_book_delta_channels: Arc::clone(&self.active_book_delta_channels),
active_book_depth10_channels: Arc::clone(&self.active_book_depth10_channels),
active_ticker_channels: Arc::clone(&self.active_ticker_channels),
active_quote_subs: Arc::clone(&self.active_quote_subs),
active_trade_subs: Arc::clone(&self.active_trade_subs),
active_mark_subs: Arc::clone(&self.active_mark_subs),View on GitHub (pinned to 18893faf8b)
Solutions
- Read the joined messages in the error to identify which underlying task(s) failed and fix the root cause (network, auth, URL).
- Check connectivity and Derive API availability, then retry connect().
- Verify credentials/API URL configuration if the underlying errors mention auth or request failures.
- Retry the disconnect()/connect() cycle; the error list is cleared via mem::take so a clean retry is possible.
Example fix
null
Defensive patterns
Strategy: try-catch
Try / catch
match client.connect().await {
Ok(()) => {},
Err(e) => {
// e may contain multiple causes joined by "; " — log all, retry after backoff
log::error!("Derive connect teardown errors: {e}");
tokio::time::sleep(BACKOFF).await;
retry_connect();
}
} Prevention
- Monitor the individual causes in the joined "; " message to fix root causes.
- Check Derive API/WebSocket reachability before connecting.
- Verify credentials and URLs before partial teardown-prone connects.
- Implement reconnect with exponential backoff.
When it happens
Trigger: Calling connect() or disconnect() when spawned subscription/stream tasks fail to complete or error out while being awaited during partial-connection cleanup (e.g. a WebSocket task panicked, errored, or the HTTP init step failed mid-connect).
Common situations: Network outages or Derive API unavailability while connecting; auth failures mid-handshake leaving tasks to fail; disconnecting while streams are in an error state; seeing multiple underlying causes joined in one message.
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
- {errors.join("; ")}
- Failed to terminate Derive execution session tasks: {e}
- std::mem::take(&mut self.shutdown_errors).join("; ")
- failed to finish Binance Futures data command tasks: {e}
- Binance Futures data teardown failed: {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/bde54aeb7b065b1d.
Report an issue: GitHub.