nautechsystems/nautilus_trader · error

Derive execution WS event receiver not initialized

Error message

Derive execution WS event receiver not initialized

What it means

After establishing the WebSocket connection, connect expects the WS client to hand over its event receiver via take_event_receiver(). If none is available (receiver already taken or never created), the client tears down and raises this error. It indicates an internal initialization failure of the Derive execution WebSocket client.

Source

Thrown at crates/adapters/derive/src/execution.rs:628

        }
        let cancellation_token = self.cancellation_token.clone();
        let ws_shutdown = self.ws_client.shutdown_handle();
        let setup_guard =
            TaskGroupGuard::new(&[&self.session_tasks, &self.pending_tasks], move || {
                cancellation_token.cancel();
                ws_shutdown.begin_shutdown();
            });

        self.ensure_instruments_initialized()
            .await
            .context("failed to initialize Derive instruments")?;

        self.ws_client
            .connect()
            .await
            .context("failed to connect Derive WebSocket")?;
        let Some(rx) = self.ws_client.take_event_receiver() else {
            let e = anyhow::anyhow!("Derive execution WS event receiver not initialized");
            if let Err(teardown_error) = self.teardown_partial_connect().await {
                return Err(e.context(format!(
                    "Derive execution startup teardown failed: {teardown_error}"
                )));
            }
            return Err(e);
        };

        let subaccount_id = self.credential.subaccount_id();
        let channels = vec![
            DeriveWsChannel::orders(subaccount_id),
            DeriveWsChannel::private_trades(subaccount_id),
            DeriveWsChannel::balances(subaccount_id),
        ];

        if let Err(e) = self.ws_client.subscribe_channels(channels).await {
            log::warn!("Derive private WS subscriptions failed: {e}; tearing down");
            if let Err(teardown_error) = self.teardown_partial_connect().await {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Recreate the Derive execution client (or its WS client) instead of reconnecting on the same instance, so the event receiver is fresh.
  2. If this occurs on a first connect, it is an internal bug — check the adapter version and report/inspect how the WS client was constructed.
  3. Upgrade to a newer version of the derive adapter in case the receiver lifecycle bug was fixed.
  4. Check whether a prior connect consumed take_event_receiver without a subsequent client reset.
Defensive patterns

Strategy: fallback

Try / catch

match exec_client.connect().await {
    Err(e) if e.to_string().contains("event receiver not initialized") => {
        // internal invariant broken — recreate the client and retry once
        let fresh = DeriveExecutionClient::new(...)?;
        fresh.connect().await?;
    }
    other => other.map(|_| ()),
}

Prevention

When it happens

Trigger: Calling connect twice on the same WS client (the receiver is taken only once, Option consumed); a WS client constructed in a way that never created the event channel; connecting after a partial failure that already consumed the receiver.

Common situations: Reusing a single execution client instance across reconnects where the receiver wasn't recreated; bespoke wiring of the WS client bypassing the adapter's constructor; internal invariant violation after a failed prior connect.

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/91a2a39ea5489e7f. Report an issue: GitHub.