{"record":{"id":"1748c647519d0b21","repo":"nautechsystems/nautilus_trader","slug":"missing-transaction-hash-in-log","errorCode":null,"errorMessage":"Missing transaction hash in log","messagePattern":"Missing transaction hash in log","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/hypersync/log.rs","lineNumber":49,"sourceCode":") -> anyhow::Result<Address> {\n    match log.topics.get(topic_index).and_then(|t| t.as_ref()) {\n        Some(topic) => core::extract_address_from_bytes(topic.as_ref()),\n        None => {\n            anyhow::bail!(\"Missing {description} address in topic{topic_index} when parsing event\")\n        }\n    }\n}\n\n/// Extracts the transaction hash from a log entry\n///\n/// # Errors\n///\n/// Returns an error if the transaction hash is not present in the log.\npub fn extract_transaction_hash(log: &HypersyncLog) -> anyhow::Result<String> {\n    log.transaction_hash\n        .as_ref()\n        .map(ToString::to_string)\n        .ok_or_else(|| anyhow::anyhow!(\"Missing transaction hash in log\"))\n}\n\n/// Extracts the transaction index from a log entry\n///\n/// # Errors\n///\n/// Returns an error if the transaction index is not present in the log.\npub fn extract_transaction_index(log: &HypersyncLog) -> anyhow::Result<u32> {\n    log.transaction_index\n        .as_ref()\n        .map(|index| **index as u32)\n        .ok_or_else(|| anyhow::anyhow!(\"Missing transaction index in the log\"))\n}\n\n/// Extracts the log index from a log entry\n///\n/// # Errors\n///","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/hypersync/log.rs#L31-L67","documentation":"extract_transaction_hash converts a Hypersync log's optional transaction_hash into a String. The error fires when the log carries no transaction hash, which would break downstream transaction correlation, so the extractor refuses to return a value.","triggerScenarios":"Calling extract_transaction_hash with a HypersyncLog whose transaction_hash field is None; this occurs with malformed or partial HyperSync responses for a log entry.","commonSituations":"HyperSync API returning incomplete log objects (schema/version drift, partial data); decoding synthetic or filtered logs that omit the hash; network/API issues yielding truncated payloads.","solutions":["Filter or re-fetch the log entry so transaction_hash is populated before extraction","Check the hypersync-client version / API schema for known fields returning None","Skip or batch-retry the affected logs in the ingestion loop","Log the offending log payload and report it if HyperSync persistently omits the hash"],"exampleFix":"// before\nlet tx_hash = extract_transaction_hash(&log)?;\n// after\nif log.transaction_hash.is_some() {\n    let tx_hash = extract_transaction_hash(&log)?;\n} else {\n    tracing::warn!(\"skipping log without tx hash\");\n}","handlingStrategy":"validation","validationCode":"fn has_tx_hash(log: &HypersyncLog) -> bool {\n    log.transaction_hash.is_some()\n}\n// skip logs where !has_tx_hash(&log) before calling extract_transaction_hash","typeGuard":"fn log_has_tx_hash(log: &HypersyncLog) -> bool {\n    log.transaction_hash.is_some()\n}","tryCatchPattern":"match extract_transaction_hash(&log) {\n    Ok(hash) => /* use hash */,\n    Err(e) => { tracing::warn!(\"skipping log: {e}\"); continue; }\n}","preventionTips":["Always request transaction_hash in HyperSync field selections","Validate required log fields immediately after each response page","Pin and test against a specific hypersync-client version"],"tags":["hypersync","blockchain","logs","missing-field"],"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"}