nautechsystems/nautilus_trader · error

Missing block number

Error message

Missing block number

What it means

This error indicates the RpcLog's block_number field is None when extract_block_number is called. Ethereum RPC logs always carry a block number in confirmed receipts, so a missing value means the log came from a pending/unmined transaction or a partially populated response. It is thrown before any hex parsing occurs.

Source

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

///
/// # Errors
///
/// Returns an error if the hex string cannot be parsed as u32.
pub fn parse_hex_u32(hex: &str) -> anyhow::Result<u32> {
    u32::from_str_radix(hex.trim_start_matches("0x"), 16)
        .map_err(|e| anyhow::anyhow!("Invalid hex u32: {e}"))
}

/// Extract block number from RPC log.
///
/// # Errors
///
/// 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
///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Only process logs once the transaction is confirmed (wait for receipt or block confirmation).
  2. Handle the None case explicitly: skip or queue pending logs instead of unwrapping.
  3. Check your RPC subscription type — switch from pending to confirmed log streams.
  4. If constructing RpcLog manually in tests, populate block_number with a hex quantity like "0x1".

Example fix

// before
let block = extract_block_number(&log)?;
// after
match extract_block_number(&log) {
    Ok(block) => process(block),
    Err(_) if log.block_number.is_none() => skip_pending_log(),
    Err(e) => return Err(e),
}
Defensive patterns

Strategy: try-catch

Validate before calling

if log.block_number.is_none() {
    // pending or synthetic log — defer or skip
}

Type guard

fn has_block_number(log: &RpcLog) -> bool { log.block_number.is_some() }

Try / catch

match extract_block_number(&log) {
    Ok(b) => handle(b),
    Err(e) if log.block_number.is_none() => defer_pending(&log),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling extract_block_number on a log from a pending transaction receipt (block_number null), on a manually constructed RpcLog, or on deserialized JSON where the field was omitted/null.

Common situations: Subscribing to pending logs via newPendingTransactions or newPendingReceipts, provider-specific responses where pending receipts omit block_number, or partial mock/test data.

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