nautechsystems/nautilus_trader · error

Failed to start Lighter data task generation: {e}

Error message

Failed to start Lighter data task generation: {e}

What it means

The Lighter data client failed while starting its background WebSocket data task generation during connect(). Any error returned by `tasks.start_generation()` (typically an internal spawn or channel setup failure) is wrapped in this message. It is thrown to abort a partially-completed connect and signals the client could not begin producing market data.

Source

Thrown at crates/adapters/lighter/src/data/mod.rs:984

        if self.is_connected()
            && self.tasks.is_open()
            && self.ws_disconnect_handle.is_none()
            && self.ws_handler_retained.is_empty()
        {
            return Ok(());
        }

        if !self.tasks.is_open()
            || !self.tasks.is_empty()
            || self.ws_disconnect_handle.is_some()
            || !self.ws_handler_retained.is_empty()
        {
            self.teardown_partial_connect().await?;
        }

        if !self.tasks.is_open() {
            self.tasks.start_generation().map_err(|e| {
                anyhow::anyhow!("Failed to start Lighter data task generation: {e}")
            })?;
            self.cancellation_token = self.tasks.cancellation_token();
        }

        let ws_client = self.ws_client.clone();
        let setup_guard = TaskGroupGuard::new(&[&self.tasks], move || {
            ws_client.begin_shutdown();
        });

        let instruments = self
            .bootstrap_instruments()
            .await
            .context("failed to bootstrap Lighter instruments")?;

        for instrument in instruments {
            if let Err(e) = self.data_sender.send(DataEvent::Instrument(instrument)) {
                log::warn!("Failed to send instrument: {e}");
            }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the wrapped inner error ({e}) to identify the underlying start_generation failure.
  2. Construct a fresh LighterDataClient instead of reusing one after a failed connect.
  3. Ensure the async runtime is healthy and not shutting down when connect() is called.
  4. Update the adapter version in case of a known task-generation bug.

Example fix

// before
let client = build_client();
client.connect().await?; // may fail after prior partial connect
// after
let client = build_client(); // rebuild a fresh client on retry
client.connect().await?;
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: check task group state before connect
assert!(!client_is_torn_down, "rebuild client instead of reusing after failed connect");

Try / catch

match client.connect().await {
    Err(e) if e.to_string().contains("Failed to start Lighter data task generation") => {
        // rebuild a fresh client and retry once
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling connect() on LighterDataClient when the internal task group's start_generation() fails — e.g. a required runtime handle is missing or the task group was already torn down after a prior partial connect failure (note the preceding teardown_partial_connect() call).

Common situations: Reconnecting after a failed connect in the same client instance; running in a runtime that is shutting down; a bug or incompatibility in the task-group infrastructure.

Related errors


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