nautechsystems/nautilus_trader · error

std::mem::take(&mut self.shutdown_errors).join("; ")

Error message

std::mem::take(&mut self.shutdown_errors).join("; ")

What it means

teardown_partial_connect on the Coinbase execution client collects errors from rolling back partially-completed connect steps (e.g. failed REST/WS setup pending_result) into shutdown_errors, then fails with all messages joined by '; '. It reports why the partially-connected exec client could not be cleanly torn down.

Source

Thrown at crates/adapters/coinbase/src/execution.rs:288

        self.abort_pending_tasks();

        if let Err(e) = self.ws_user.disconnect().await {
            self.shutdown_errors.push(e.to_string());
        }
        let (session_result, pending_result) =
            tokio::join!(self.await_session_tasks(), self.await_pending_tasks());
        self.core.set_disconnected();

        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(())
    }

    // Returns true when the exec client was created with a Margin account,
    // indicating it should handle CFM-backed derivatives traffic.
    fn is_margin(&self) -> bool {
        self.core.account_type == AccountType::Margin
    }

    // Returns true when the instrument resides in the connect-time bootstrap
    // cache. For the Cash (spot) factory this gates spot-only traffic; for the
    // Margin factory the cache contains CFM perp + future products.
    fn is_instrument_cached(&self, instrument_id: &InstrumentId) -> bool {
        self.instruments_cache
            .contains_key(instrument_id.symbol.as_str())
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the joined '; ' message to find which teardown step failed
  2. Retry the full connect with a freshly constructed execution client rather than reusing the half-torn-down one
  3. Verify API credentials and network reachability before connect so the partial path is not entered
  4. If disconnect reports the socket was already closed, treat teardown as complete and recreate the client
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: verify credentials/network before connect
assert!(!api_key.is_empty() && !api_secret.is_empty());

Try / catch

if let Err(e) = exec_client.connect().await {
    // teardown errors are '; '-joined; log then rebuild a fresh client
    log::error!("coinbase exec connect/teardown failed: {e}");
    exec_client = CoinbaseExecClientFactory::create(...)?;
}

Prevention

When it happens

Trigger: connect() on the execution client fails midway (e.g. account registration, WS setup) and the rollback's pending_result error, or a ws/REST disconnect error, populates shutdown_errors.

Common situations: Invalid API keys failing mid-connect; network outage during connect; disconnect called on an already-dead connection during rollback.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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