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
- Read the joined '; ' message to find which teardown step failed
- Retry the full connect with a freshly constructed execution client rather than reusing the half-torn-down one
- Verify API credentials and network reachability before connect so the partial path is not entered
- 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
- Verify API keys/scopes before connecting to avoid partial-connect paths
- Never reuse an execution client after a teardown error — rebuild it
- Serialize connect/disconnect calls per client
- Parse the joined teardown messages to identify the failing step
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
- std::mem::take(&mut self.shutdown_errors).join("; ")
- Invalid config type for AxExecutionClientFactory. Expected A
- option_summary_family_subs mutex poisoned
- Binance Spot data teardown failed: {}
- Timeout waiting for account {account_id} to be registered af
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e8c523256efddedd.
Report an issue: GitHub.