nautechsystems/nautilus_trader · error

Missing transaction hash

Error message

Missing transaction hash

What it means

This error means the RpcLog's transaction_hash field is None when extract_transaction_hash is called. The transaction hash is expected on every confirmed log, so its absence indicates a pending log, a synthetic log, or an incomplete RPC response. Thrown before any parsing, as a simple Option unwrap guard.

Source

Thrown at crates/adapters/blockchain/src/rpc/log.rs:74

///
/// Returns an error if the block number is missing or cannot be parsed.
pub fn extract_block_number(log: &RpcLog) -> anyhow::Result<u64> {
    let hex = log
        .block_number
        .as_ref()
        .ok_or_else(|| anyhow::anyhow!("Missing block number"))?;
    parse_hex_u64(hex)
}

/// Extract transaction hash from RPC log.
///
/// # Errors
///
/// Returns an error if the transaction hash is missing.
pub fn extract_transaction_hash(log: &RpcLog) -> anyhow::Result<String> {
    log.transaction_hash
        .clone()
        .ok_or_else(|| anyhow::anyhow!("Missing transaction hash"))
}

/// Extract transaction index from RPC log.
///
/// # Errors
///
/// Returns an error if the transaction index is missing or cannot be parsed.
pub fn extract_transaction_index(log: &RpcLog) -> anyhow::Result<u32> {
    let hex = log
        .transaction_index
        .as_ref()
        .ok_or_else(|| anyhow::anyhow!("Missing transaction index"))?;
    parse_hex_u32(hex)
}

/// Extract log index from RPC log.
///
/// # Errors

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Wait for transaction confirmation before processing logs.
  2. Skip logs lacking a transaction hash (they cannot be attributed to a tx).
  3. Check the RPC provider's response shape — some providers use different field casing; verify deserialization maps transactionHash correctly.
  4. Populate transaction_hash in manually constructed test logs.

Example fix

// before
let tx_hash = extract_transaction_hash(&log)?;
// after
if log.transaction_hash.is_none() {
    return Ok(()); // skip pending/unattributed log
}
let tx_hash = extract_transaction_hash(&log)?;
Defensive patterns

Strategy: try-catch

Validate before calling

if log.transaction_hash.is_none() {
    // log not attributable to a transaction — skip or defer
}

Type guard

fn has_tx_hash(log: &RpcLog) -> bool { log.transaction_hash.is_some() }

Try / catch

let Ok(tx_hash) = extract_transaction_hash(&log) else {
    skip_log(&log); return Ok(());
};

Prevention

When it happens

Trigger: Calling extract_transaction_hash on a pending-transaction log, a hand-built RpcLog, or JSON deserialized from a response that omitted transactionHash.

Common situations: Pending log subscriptions, lightweight providers that trim log payloads, or tests using minimal fixtures without hashes.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/a800440d494cc474. Report an issue: GitHub.