nautechsystems/nautilus_trader · error
WebSocket client not initialized
Error message
WebSocket client not initialized
What it means
DeribitDataApp's WebSocket client is created during connect(); before that, ws_client is None. ws_client_mut unwraps it and throws this error when any code path (e.g. connect's handshake/subscribe steps) tries to mutate or use the client before initialization. It signals a lifecycle-ordering bug rather than a network failure.
Source
Thrown at crates/adapters/deribit/src/data.rs:200
is_connected: AtomicBool::new(false),
cancellation_token: session_tasks.cancellation_token(),
session_tasks,
command_tasks,
data_sender,
instruments: Arc::new(AtomicMap::new()),
mark_price_subs: Arc::new(AtomicSet::new()),
index_price_subs: Arc::new(AtomicSet::new()),
option_greeks_subs: Arc::new(AtomicSet::new()),
combo_leg_trade_subs: Arc::new(AtomicMap::new()),
clock,
})
}
/// Returns a mutable reference to the WebSocket client.
fn ws_client_mut(&mut self) -> anyhow::Result<&mut DeribitWebSocketClient> {
self.ws_client
.as_mut()
.ok_or_else(|| anyhow::anyhow!("WebSocket client not initialized"))
}
fn spawn_command<F>(&self, future: F)
where
F: std::future::Future<Output = ()> + Send + 'static,
{
if let Err(e) = self.command_tasks.spawn(future) {
log::warn!("Skipping Deribit data command after shutdown began: {e}");
}
}
async fn finish_tasks(&self) -> anyhow::Result<()> {
let (session_result, command_result) = tokio::join!(
self.session_tasks
.finish_shutdown(Duration::from_secs(1), Duration::from_secs(2)),
self.command_tasks
.finish_shutdown(Duration::from_secs(1), Duration::from_secs(2)),
);View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure connect() completes (await it) before any other data-app methods that use the WebSocket client.
- Guard call order in your integration: only subscribe/request after the connection-ready callback/state.
- If reconnecting, verify the reconnect path re-initializes ws_client before dispatching commands.
- For tests, initialize the WS client (or the app) exactly as connect() does before exercising these paths.
Example fix
// before let app = DeribitDataApp::new(config); app.subscribe_quotes(instrument_id).await?; // ws not initialized // after let app = DeribitDataApp::new(config); app.connect().await?; // initializes ws_client app.subscribe_quotes(instrument_id).await?;
Defensive patterns
Strategy: validation
Validate before calling
// Rust
anyhow::ensure!(
app.is_connected(),
"call connect() before any WebSocket-dependent operation"
); Try / catch
match app.connect().await {
Ok(()) => app.subscribe_quotes(id).await?,
Err(e) if e.to_string().contains("not initialized") => {
return Err(anyhow!("data app not connected; connect() must run first: {e}"));
}
Err(e) => return Err(e),
} Prevention
- Await connect() before any subscribe/request calls
- Serialize connect/reconnect so it cannot race with subscriptions
- Gate subscriptions on a connected-state flag or callback
When it happens
Trigger: Calling methods that require the WS client (connect internals, command dispatch, subscription calls) before initialize/connection — e.g. double connect racing, calling a subscribe/quotes path without prior connect, or a callback firing before connection completes.
Common situations: Subscribing immediately after constructing the data app without awaiting connection; reconnect logic racing with initial connect; tests instantiating DeribitDataApp without a WS client and invoking ws_client_mut paths.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- InstrumentState channel requires kind and currency parameter
- std::mem::take(&mut self.shutdown_errors).join("; ")
- WebSocket output receiver not available
- errors joined with "; " (aggregated disconnect errors)
- errors joined with "; " (aggregated disconnect errors)
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/c0bc7a0c06cf7cec.
Report an issue: GitHub.