{"record":{"id":"e21368101c81b7ba","repo":"nautechsystems/nautilus_trader","slug":"swap-decision-header-conflicts-with-profiler-ances","errorCode":null,"errorMessage":"Swap decision header conflicts with profiler ancestry","messagePattern":"Swap decision header conflicts with profiler ancestry","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":3999,"sourceCode":"        validate_profiler_event_verified(\n            position,\n            expected_block_hash,\n            plan.pool_address,\n            &plan.pool,\n            verification,\n        )\n        .await?;\n    }\n\n    let ancestry = verified_value(\n        verification\n            .verify_header_window(canonical_block, head.number)\n            .await,\n        \"profiler-to-decision ancestry\",\n    )?;\n\n    if let Some(last) = ancestry.last() {\n        anyhow::ensure!(\n            *last == head,\n            \"Swap decision header conflicts with profiler ancestry\"\n        );\n    } else {\n        anyhow::ensure!(\n            canonical_block == head,\n            \"Empty profiler ancestry does not end at the decision header\"\n        );\n    }\n    verified_value(\n        verification\n            .verify_deployment_manifest(manifest, head.number)\n            .await,\n        \"swap deployment manifest\",\n    )?;\n    let quote_contract = validate_manifest_pool(plan, manifest)?;\n    let quote_kind = match plan.order.order_side() {\n        OrderSide::Sell => SwapQuoteKind::ExactInput(quantity_to_raw_amount(","sourceCodeStart":3981,"sourceCodeEnd":4017,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L3981-L4017","documentation":"After fetching the canonical decision header, the library walks the header ancestry from the profiler watermark block to the decision head via verify_header_window. The last ancestry header must be exactly the decision head; otherwise the verified window disagrees with the header used for the swap decision, indicating a reorg or inconsistent verification results. Execution is aborted.","triggerScenarios":"During swap quote validation, verify_header_window(canonical_block, head.number) returns a non-empty ancestry whose last element != head — i.e. the chain reorganized between the ancestry fetch and the head fetch, or two verification calls hit different forks.","commonSituations":"Active reorgs on the target chain during execution; load-balanced RPC endpoints serving different forks; verifier cache out of sync; attempting execution during unstable network conditions right after a chain reorganization event.","solutions":["Retry execution after the reorg settles; the window is re-verified each attempt.","Pin RPC/verification traffic to a single consistent endpoint instead of load-balanced forks.","Refresh the profiler watermark and re-derive both the canonical block and head.","Increase confirmation depth (max_age_blocks / head lag) so decisions are not made near reorg-prone tips."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"let ancestry = verification.verify_header_window(canonical_block, head.number).await?;\nif let Some(last) = ancestry.last() {\n    if *last != head {\n        anyhow::bail!(\"decision head not on verified ancestry; reorg in progress\");\n    }\n}","typeGuard":null,"tryCatchPattern":"match build_quote_anchors(...).await {\n    Ok(a) => execute(a),\n    Err(e) if e.to_string().contains(\"conflicts with profiler ancestry\") => {\n        tokio::time::sleep(backoff).await; // let the reorg settle\n        retry();\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Use one dedicated RPC endpoint for all verification calls to avoid fork skew.","Add short retry with backoff around ancestry verification.","Pause trading during detected reorg windows."],"tags":["blockchain","reorg","consistency-check","race-condition"],"backgroundTag":"checksum-mismatch","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}