nautechsystems/nautilus_trader · error · anyhow::Error

Profiler receipt contains

Error message

Profiler receipt contains {} logs at global index {}; expected exactly one

What it means

During profiler watermark verification, the library filters the transaction receipt's logs for one whose global log index matches the ingestion watermark's log_index, and requires exactly one match. If zero or multiple logs carry that index, the watermark cannot be unambiguously resolved, so the library throws rather than guessing.

Solutions

  1. Log the receipt's full log list with extracted indices and compare against position.log_index to see whether it is 0 or >1 matches.
  2. Re-fetch the receipt from a different/fuller RPC provider if logs appear truncated.
  3. Verify the watermark position was produced by the same node/provider that serves the receipt.
  4. Upgrade or fix the node indexing if duplicate log indices are returned.
Defensive patterns

Strategy: validation

Validate before calling

let matches: Vec<_> = receipt.logs.iter()
    .filter(|l| extract_log_index(l).ok() == Some(position.log_index))
    .collect();
if matches.len() != 1 { /* re-fetch receipt from another provider */ }

Try / catch

match client.validate_watermark_log(&receipt, &position).await {
    Ok(log) => log,
    Err(e) if e.to_string().contains("expected exactly one") => fallback_provider_fetch(e),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling the profiler validation with a receipt whose logs either do not contain the log at position.log_index (0 matches, e.g. logs truncated by the RPC provider) or where extract_log_index returns the same index for multiple logs (duplicate indexing by a broken RPC).

Common situations: RPC providers that omit or truncate receipt logs; misconfigured tracing/indexing nodes; a data-feed watermark advanced past what the execution node has; provider bugs returning duplicated log entries.

Related errors


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

Appendix: source

Thrown at crates/adapters/blockchain/src/execution/client.rs:4213

        receipt.status,
        "Profiler transaction did not execute successfully"
    );
    anyhow::ensure!(
        receipt.transaction_hash == transaction_hash,
        "Profiler receipt transaction hash does not match its ingestion watermark"
    );
    anyhow::ensure!(
        receipt.block_number == position.number
            && receipt.block_hash == expected_block_hash
            && receipt.transaction_index == u64::from(position.transaction_index),
        "Profiler receipt position does not match its ingestion watermark"
    );
    let matching_logs = receipt
        .logs
        .iter()
        .filter(|log| rpc_log::extract_log_index(log).ok() == Some(position.log_index))
        .collect::<Vec<_>>();
    anyhow::ensure!(
        matching_logs.len() == 1,
        "Profiler receipt contains {} logs at global index {}; expected exactly one",
        matching_logs.len(),
        position.log_index
    );
    let log = matching_logs[0];
    let log_transaction_hash = B256::from_str(&rpc_log::extract_transaction_hash(log)?)
        .with_context(|| "Invalid profiler log transaction hash")?;
    let log_block_hash = log
        .block_hash
        .as_deref()
        .ok_or_else(|| anyhow::anyhow!("Profiler log has no block hash"))?;
    anyhow::ensure!(
        !log.removed
            && log_transaction_hash == transaction_hash
            && rpc_log::extract_block_number(log)? == position.number
            && rpc_log::extract_transaction_index(log)? == position.transaction_index
            && B256::from_str(log_block_hash)? == expected_block_hash,

View on GitHub (pinned to 18893faf8b)