nautechsystems/nautilus_trader · error

Missing transaction index

Error message

Missing transaction index

What it means

This error means the RpcLog's transaction_index field is None when extract_transaction_index is called. Transaction index is the position of the transaction within its block; it is absent on pending transactions before mining. Thrown before hex parsing.

Source

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

/// # 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
///
/// Returns an error if the log index is missing or cannot be parsed.
pub fn extract_log_index(log: &RpcLog) -> anyhow::Result<u32> {
    let hex = log
        .log_index
        .as_ref()
        .ok_or_else(|| anyhow::anyhow!("Missing log index"))?;
    parse_hex_u32(hex)
}

/// Extract contract address from RPC log.
///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Process logs only after the transaction is mined/confirmed.
  2. Handle None explicitly: skip or defer the log.
  3. Verify the RPC response includes transactionIndex (check provider docs and serde field naming).
  4. Set transaction_index (e.g. "0x0") in hand-built logs for tests.

Example fix

// before
let idx = extract_transaction_index(&log)?;
// after
let Some(_) = log.transaction_index else { skip_pending_log(); return Ok(()) };
let idx = extract_transaction_index(&log)?;
Defensive patterns

Strategy: validation

Validate before calling

if log.transaction_index.is_none() {
    // pending log — defer until mined
}

Type guard

fn has_tx_index(log: &RpcLog) -> bool { log.transaction_index.is_some() }

Try / catch

let idx = match extract_transaction_index(&log) {
    Ok(i) => i,
    Err(_) if log.transaction_index.is_none() => { defer(&log); return Ok(()); }
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: Calling extract_transaction_index on a log from a pending receipt, on a manually constructed RpcLog, or on deserialized JSON missing transactionIndex.

Common situations: Pending log streams, nonstandard providers omitting index fields, or incomplete test fixtures.

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/7942b6739ba85d08. Report an issue: GitHub.