nautechsystems/nautilus_trader · error · anyhow::Error

Failed to start Bybit task generation: {e}

Error message

Failed to start Bybit task generation: {e}

What it means

connect() restarts the execution client's background task generation. If pending tasks were not open, it awaits their termination then calls start_generation(); a failure there is wrapped in this error to abort the connect sequence with context.

Source

Thrown at crates/adapters/bybit/src/execution.rs:738

        self.product_types().contains(&product_type)
            && Self::provides_bulk_position_coverage_for_product_type(product_type)
    }

    async fn connect(&mut self) -> anyhow::Result<()> {
        if self.core.is_connected() && self.pending_tasks.is_open() && self.session_tasks.is_open()
        {
            return Ok(());
        }

        if !self.pending_tasks.is_open() || !self.session_tasks.is_open() {
            self.teardown_partial_connect().await?;
        }

        if !self.pending_tasks.is_open() {
            self.await_pending_tasks().await?;
            self.pending_tasks
                .start_generation()
                .map_err(|e| anyhow::anyhow!("Failed to start Bybit task generation: {e}"))?;
        }

        if !self.session_tasks.is_open() {
            self.await_session_tasks().await?;
            self.session_tasks
                .start_generation()
                .map_err(|e| anyhow::anyhow!("Failed to start Bybit session generation: {e}"))?;
        }
        let http_client = self.http_client.clone();
        let ws_private = self.ws_private.clone();
        let ws_trade = self.ws_trade.clone();
        let setup_guard =
            TaskGroupGuard::new(&[&self.session_tasks, &self.pending_tasks], move || {
                http_client.cancel_all_requests();
                ws_private.begin_shutdown();
                ws_trade.begin_shutdown();
            });

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the inner error {e} for the task group failure cause
  2. Create a fresh client instance instead of reusing a fully torn-down one
  3. Ensure the tokio runtime is alive when calling connect
  4. Check that disconnect completed cleanly before reconnecting
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure a live runtime and a cleanly disconnected client before connect():
// assert client not connected and runtime handle available.

Try / catch

match client.connect().await {
    Ok(()) => {}
    Err(e) if e.to_string().contains("task generation") => {
        tracing::error!("connect failed starting task generation: {e}; recreating client");
        client = BybitExecutionClient::new(/* fresh deps */).await?;
        client.connect().await?;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling connect on BybitExecutionClient when the previous task generation is closed and starting a new one fails (e.g. runtime shut down, task group in bad state).

Common situations: Reconnecting after a fault where the tokio runtime or task group was already torn down; double-disconnect followed by 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/db39f9820fce8e6c. Report an issue: GitHub.