{"record":{"id":"4e85727159092764","repo":"nautechsystems/nautilus_trader","slug":"profiler-log-has-no-block-hash","errorCode":null,"errorMessage":"Profiler log has no block hash","messagePattern":"Profiler log has no block hash","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":4225,"sourceCode":"    );\n    let matching_logs = receipt\n        .logs\n        .iter()\n        .filter(|log| rpc_log::extract_log_index(log).ok() == Some(position.log_index))\n        .collect::<Vec<_>>();\n    anyhow::ensure!(\n        matching_logs.len() == 1,\n        \"Profiler receipt contains {} logs at global index {}; expected exactly one\",\n        matching_logs.len(),\n        position.log_index\n    );\n    let log = matching_logs[0];\n    let log_transaction_hash = B256::from_str(&rpc_log::extract_transaction_hash(log)?)\n        .with_context(|| \"Invalid profiler log transaction hash\")?;\n    let log_block_hash = log\n        .block_hash\n        .as_deref()\n        .ok_or_else(|| anyhow::anyhow!(\"Profiler log has no block hash\"))?;\n    anyhow::ensure!(\n        !log.removed\n            && log_transaction_hash == transaction_hash\n            && rpc_log::extract_block_number(log)? == position.number\n            && rpc_log::extract_transaction_index(log)? == position.transaction_index\n            && B256::from_str(log_block_hash)? == expected_block_hash,\n        \"Profiler log position does not match its ingestion watermark\"\n    );\n    anyhow::ensure!(\n        rpc_log::extract_address(log)? == pool_address,\n        \"Profiler watermark log did not come from expected pool {pool_address}\"\n    );\n    let signature = log\n        .topics\n        .first()\n        .ok_or_else(|| anyhow::anyhow!(\"Profiler watermark log has no event signature\"))?;\n    let supported =\n        profiler_event_signatures(pool).any(|expected| expected.eq_ignore_ascii_case(signature));","sourceCodeStart":4207,"sourceCodeEnd":4243,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L4207-L4243","documentation":"The profiler watermark log extracted from a receipt must carry a block_hash field to verify it belongs to the expected block. This error is thrown when the RPC-returned log has a null/missing block_hash, so the position check cannot proceed.","triggerScenarios":"Calling profiler validation when the log object returned by eth_getTransactionReceipt (or a log subscription) has block_hash: null or omits the field entirely.","commonSituations":"Pending logs (not yet mined) delivered by a websocket subscription; lightweight RPC providers that strip fields; log objects reconstructed manually or from partial eth_getFilterChanges payloads.","solutions":["Wait until the log is mined (block_hash present) before running profiler validation.","Use a full RPC provider that returns complete log objects (eth_getLogs/eth_getTransactionReceipt) instead of a stripped proxy.","Check client/provider version for known bugs omitting block_hash and upgrade.","Re-fetch the receipt via eth_getTransactionReceipt, which should always include block_hash for mined transactions."],"exampleFix":"// before: subscribing and validating immediately\nlet log = next_pending_log(&ws).await;\nvalidate_profiler_log(&log, &position)?;\n\n// after: only validate mined logs\nlet log = next_pending_log(&ws).await;\nif log.block_hash.is_none() {\n    log = fetch_receipt_log(&rpc, tx_hash, position.log_index).await?;\n}\nvalidate_profiler_log(&log, &position)?;","handlingStrategy":"validation","validationCode":"if log.block_hash.is_none() {\n    // fetch the mined receipt instead of a pending log\n    receipt = rpc.get_transaction_receipt(tx_hash).await?;\n}","typeGuard":"fn has_block_hash(log: &Log) -> bool {\n    log.block_hash.as_deref().map(|h| h.len() == 66).unwrap_or(false)\n}","tryCatchPattern":"match validate_profiler_log(&log, &position) {\n    Ok(()) => Ok(()),\n    Err(e) if e.to_string().contains(\"no block hash\") => fetch_mined_log_and_retry(e),\n    Err(e) => Err(e),\n}","preventionTips":["Only validate logs that are already mined (block_hash present)","Avoid lightweight RPC proxies that strip log fields","Keep provider clients up to date"],"tags":["blockchain","logs","missing-field","rpc"],"backgroundTag":"missing-required-argument","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"}