{"record":{"id":"6a0643641d197de7","repo":"nautechsystems/nautilus_trader","slug":"invalid-block-scoped-snapshot-hash","errorCode":null,"errorMessage":"Invalid block-scoped snapshot hash","messagePattern":"Invalid block-scoped snapshot hash","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":3976,"sourceCode":"        canonical_block.hash == expected_block_hash,\n        \"Pool state block {} changed from {} to {}; refresh the profiler before execution\",\n        position.number,\n        expected_block_hash,\n        canonical_block.hash\n    );\n\n    let snapshot_transaction = position.transaction_index == BLOCK_SCOPED_SNAPSHOT_INDEX;\n    let snapshot_log = position.log_index == BLOCK_SCOPED_SNAPSHOT_INDEX;\n    anyhow::ensure!(\n        snapshot_transaction == snapshot_log,\n        \"Pool state at block {} has an invalid partial snapshot watermark\",\n        position.number\n    );\n\n    if snapshot_transaction {\n        let snapshot_hash = B256::from_str(&position.transaction_hash)\n            .with_context(|| \"Invalid block-scoped snapshot hash\")?;\n        anyhow::ensure!(\n            snapshot_hash == expected_block_hash,\n            \"Block-scoped snapshot hash {snapshot_hash} does not match ingestion hash {expected_block_hash}\"\n        );\n    } else {\n        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,","sourceCodeStart":3958,"sourceCodeEnd":3994,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L3958-L3994","documentation":"For a block-scoped snapshot row, the stored transaction_hash must be a valid 32-byte B256 hex value; the ingestion-time block hash doubles as the snapshot's transaction hash. If the field cannot be parsed as B256, the row is malformed and processing stops. The subsequent check (not this error) also requires it to equal the expected block hash.","triggerScenarios":"Parsing position.transaction_hash with B256::from_str fails during block-scoped-snapshot handling — e.g. the field holds a placeholder, empty string, non-hex text, or wrong-length hash.","commonSituations":"An indexer version writing placeholder snapshot hashes; manual data fixes with malformed hex; a schema change that repurposed transaction_hash; snapshots copied across deployments with different encodings.","solutions":["Re-ingest the block-scoped snapshot so transaction_hash is written as the proper block hash hex.","Backfill the row with the correct block hash (0x-prefixed 64 hex chars) if re-ingestion isn't possible.","Upgrade or fix the indexer component that produced the malformed hash.","Validate snapshot rows at write time to reject non-B256 values early."],"exampleFix":"// before\nposition.transaction_hash = \"snapshot\".to_string();\n\n// after: store the block hash as the snapshot marker\nposition.transaction_hash = format!(\"{:#x}\", block_hash); // valid B256 hex","handlingStrategy":"validation","validationCode":"if B256::from_str(&position.transaction_hash).is_err() {\n    anyhow::bail!(\"snapshot row at block {} has malformed transaction_hash\", position.number);\n}","typeGuard":"fn valid_snapshot_hash(position: &PoolStatePosition) -> bool {\n    B256::from_str(&position.transaction_hash).is_ok()\n}","tryCatchPattern":null,"preventionTips":["Only write 0x-prefixed 32-byte hex into transaction_hash.","Validate hex fields at ingest boundaries (deserialize into B256).","Backfill placeholder hashes by re-running the indexer for affected blocks."],"tags":["data-corruption","invalid-format","hex-parsing"],"backgroundTag":"invalid-argument-format","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"}