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

  1. Ensure connect() completes (await it) before any other data-app methods that use the WebSocket client.
  2. Guard call order in your integration: only subscribe/request after the connection-ready callback/state.
  3. If reconnecting, verify the reconnect path re-initializes ws_client before dispatching commands.
  4. 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

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


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