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

  1. Read the joined messages to identify the FIRST root-cause error (earliest in the '; '-joined string)
  2. Fix the original connect failure (auth, network, config) — teardown errors are usually secondary
  3. Check endpoint connectivity and retry connect after the network stabilizes
  4. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/edd9f8b2429f4999. Report an issue: GitHub.