nautechsystems/nautilus_trader · error

analysis task did not complete: {join_error}

Error message

analysis task did not complete: {join_error}

What it means

In `run_analyze_pools`, each pool's analysis runs in a spawned tokio task joined via its `JoinHandle`. If `handle.await` returns a `JoinError`, the task itself panicked or was cancelled; this error wraps that failure since the pool's `Result` was never produced.

Source

Thrown at crates/cli/src/blockchain/analyze.rs:206

                from_block,
                to_block,
                reset,
                require_existing_snapshot,
                &checkpoint_blocks,
                skip_validation,
                snapshot_from_rpc,
            )
            .await
        });
        tasks.push((task_address, handle));
    }

    let mut failures = 0usize;

    for (pool_address, handle) in tasks {
        let result = match handle.await {
            Ok(result) => result,
            Err(join_error) => Err(anyhow::anyhow!(
                "analysis task did not complete: {join_error}"
            )),
        };

        match result {
            Ok(outcomes) => {
                for outcome in &outcomes {
                    println!("{}", outcome.to_json(&chain_name, &dex_name));
                }
            }
            Err(e) => {
                failures = failures.saturating_add(1);
                println!(
                    "{}",
                    pool_failure_json(
                        &chain_name,
                        &dex_name,
                        &pool_address,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the wrapped `JoinError` message to identify the panicking pool and the underlying panic cause.
  2. Rerun with `RUST_BACKTRACE=1` on the single failing pool (`run_analyze_pool`) to get the panic backtrace.
  3. Fix the panic source inside the analysis code (unwrap/index/overflow) rather than treating it as data error.
  4. Ensure the tokio runtime is not shut down while tasks are in flight (await all handles before exit).

Example fix

// before
let result = handle.await?;
// after
let result = handle.await
    .unwrap_or_else(|e| Err(anyhow::anyhow!("analysis task did not complete: {e}")));
Defensive patterns

Strategy: try-catch

Try / catch

// RUST_BACKTRACE=full nautilus blockchain analyze-pool ...
match handle.await {
    Ok(Ok(outcomes)) => { /* ... */ }
    Ok(Err(e)) => eprintln!("pool failed: {e:#}"),
    Err(join) => eprintln!("task panicked/cancelled: {join}"),
}

Prevention

When it happens

Trigger: Calling `nautilus` blockchain pool analysis over multiple pools when one spawned task panics (e.g. a bug inside `analyze_pool_with_client`) or is aborted (runtime shutdown, `abort()`).

Common situations: Panic inside async analysis code (unwraps, index panics); tokio runtime teardown while tasks still run; Ctrl-C aborting the multi-pool run.

Related errors


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