{"record":{"id":"9c7ac0d4653db6e6","repo":"nautechsystems/nautilus_trader","slug":"analysis-task-did-not-complete-join-error","errorCode":null,"errorMessage":"analysis task did not complete: {join_error}","messagePattern":"analysis task did not complete: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/blockchain/analyze.rs","lineNumber":206,"sourceCode":"                from_block,\n                to_block,\n                reset,\n                require_existing_snapshot,\n                &checkpoint_blocks,\n                skip_validation,\n                snapshot_from_rpc,\n            )\n            .await\n        });\n        tasks.push((task_address, handle));\n    }\n\n    let mut failures = 0usize;\n\n    for (pool_address, handle) in tasks {\n        let result = match handle.await {\n            Ok(result) => result,\n            Err(join_error) => Err(anyhow::anyhow!(\n                \"analysis task did not complete: {join_error}\"\n            )),\n        };\n\n        match result {\n            Ok(outcomes) => {\n                for outcome in &outcomes {\n                    println!(\"{}\", outcome.to_json(&chain_name, &dex_name));\n                }\n            }\n            Err(e) => {\n                failures = failures.saturating_add(1);\n                println!(\n                    \"{}\",\n                    pool_failure_json(\n                        &chain_name,\n                        &dex_name,\n                        &pool_address,","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/cli/src/blockchain/analyze.rs#L188-L224","documentation":"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.","triggerScenarios":"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()`).","commonSituations":"Panic inside async analysis code (unwraps, index panics); tokio runtime teardown while tasks still run; Ctrl-C aborting the multi-pool run.","solutions":["Read the wrapped `JoinError` message to identify the panicking pool and the underlying panic cause.","Rerun with `RUST_BACKTRACE=1` on the single failing pool (`run_analyze_pool`) to get the panic backtrace.","Fix the panic source inside the analysis code (unwrap/index/overflow) rather than treating it as data error.","Ensure the tokio runtime is not shut down while tasks are in flight (await all handles before exit)."],"exampleFix":"// before\nlet result = handle.await?;\n// after\nlet result = handle.await\n    .unwrap_or_else(|e| Err(anyhow::anyhow!(\"analysis task did not complete: {e}\")));","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// RUST_BACKTRACE=full nautilus blockchain analyze-pool ...\nmatch handle.await {\n    Ok(Ok(outcomes)) => { /* ... */ }\n    Ok(Err(e)) => eprintln!(\"pool failed: {e:#}\"),\n    Err(join) => eprintln!(\"task panicked/cancelled: {join}\"),\n}","preventionTips":["Avoid unwrap/expect inside analysis tasks.","Await all JoinHandles before runtime shutdown; handle Ctrl-C gracefully."],"tags":["async","panic","tokio","cli"],"backgroundTag":"task-join-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}