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
teardown_partial_connect collects errors encountered while unwinding a partially completed connect (or during disconnect), accumulating them in self.shutdown_errors. If any accumulated, it joins them with '; ' and bails so no teardown failure is silently swallowed.
Source
Thrown at crates/adapters/derive/src/execution.rs:435
if let Err(e) = self.ws_client.disconnect().await {
self.shutdown_errors
.push(format!("Derive WebSocket shutdown failed: {e}"));
}
let (session_result, pending_result) =
tokio::join!(self.await_session_tasks(), self.await_pending_tasks());
self.core.set_disconnected();
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 start_ws_dispatch(
&self,
rx: tokio::sync::mpsc::UnboundedReceiver<DeriveWsMessage>,
) -> anyhow::Result<()> {
let emitter = self.emitter.clone();
let account_id = self.core.account_id;
let clock = self.clock;
let cancellation = self.cancellation_token.clone();
let dispatch_state = self.dispatch_state.clone();
let reconciliation = self.reconciliation_context();
let is_connected = Arc::clone(&self.is_connected);
let session_spawner = self
.session_tasks
.spawner()View on GitHub (pinned to 18893faf8b)
Solutions
- Read the joined messages to identify the FIRST root-cause error (earliest in the '; '-joined string)
- Fix the original connect failure (auth, network, config) — teardown errors are usually secondary
- Check endpoint connectivity and retry connect after the network stabilizes
- If disconnect errors persist, ensure components are idempotently stoppable
Example fix
// before (diagnose from joined string)
Err(e) => eprintln!("{}", e) // "task join failed; ws close failed"
// after — handle root cause first
if e.to_string().contains("auth") { fix_credentials()?; } Defensive patterns
Strategy: try-catch
Try / catch
if let Err(e) = client.connect().await {
// first '; '-joined segment is the primary teardown error; root cause is usually earlier in connect logs
for part in e.to_string().split("; ") { log::error!("shutdown: {part}"); }
} Prevention
- Ensure WS/HTTP tasks are cancellable and close is idempotent
- Handle network loss gracefully so teardown steps don't cascade
- Retry connect after transient network failures instead of treating teardown errors as fatal root causes
When it happens
Trigger: connect() fails partway (e.g. auth WS fails after HTTP init) and cleanup steps (closing sessions, cancelling tasks) also fail; or disconnect() encounters errors while stopping multiple components.
Common situations: Network drops mid-connect so both the primary step and its cleanup fail; calling disconnect while WS tasks are already dead; cascading failures after credential rejection.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Close command should not be drained
- failed to finish Binance Futures data command tasks: {e}
- Binance Futures data teardown failed: {}
- std::mem::take(&mut self.shutdown_errors).join("; ")
- std::mem::take(&mut self.shutdown_errors).join("; ")
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/edd9f8b2429f4999.
Report an issue: GitHub.