nautechsystems/nautilus_trader · error · anyhow::Error
Pool state at block {} has an invalid partial snapshot water
Error message
Pool state at block {} has an invalid partial snapshot watermark What it means
Block-scoped snapshots are recorded as a single watermark where transaction_index and log_index must both equal the sentinel BLOCK_SCOPED_SNAPSHOT_INDEX. If exactly one of them matches, the snapshot row is only partially written or corrupted, and the library cannot tell whether the event is a snapshot marker or a normal event. It rejects the row as invalid.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:3967
verification.verify_decision_header(now_unix_secs).await,
"swap decision header",
)?;
validate_quote_age(position.number, head.number, max_age_blocks)?;
let canonical_block = verified_value(
verification.verify_block(position.number).await,
"profiler watermark header",
)?;
anyhow::ensure!(
canonical_block.hash == expected_block_hash,
"Pool state block {} changed from {} to {}; refresh the profiler before execution",
position.number,
expected_block_hash,
canonical_block.hash
);
let snapshot_transaction = position.transaction_index == BLOCK_SCOPED_SNAPSHOT_INDEX;
let snapshot_log = position.log_index == BLOCK_SCOPED_SNAPSHOT_INDEX;
anyhow::ensure!(
snapshot_transaction == snapshot_log,
"Pool state at block {} has an invalid partial snapshot watermark",
position.number
);
if snapshot_transaction {
let snapshot_hash = B256::from_str(&position.transaction_hash)
.with_context(|| "Invalid block-scoped snapshot hash")?;
anyhow::ensure!(
snapshot_hash == expected_block_hash,
"Block-scoped snapshot hash {snapshot_hash} does not match ingestion hash {expected_block_hash}"
);
} else {
validate_profiler_event_verified(
position,
expected_block_hash,
plan.pool_address,
&plan.pool,View on GitHub (pinned to 18893faf8b)
Solutions
- Re-ingest the snapshot for that block so both transaction_index and log_index are set (or unset) consistently.
- Fix the indexer/writer to set both sentinel fields atomically.
- Check for in-progress writes or migrations touching that row and re-run them.
- If the row should be a normal event, clear both sentinel fields.
Example fix
// before: partially set sentinel position.transaction_index = BLOCK_SCOPED_SNAPSHOT_INDEX; // after: set both atomically position.transaction_index = BLOCK_SCOPED_SNAPSHOT_INDEX; position.log_index = BLOCK_SCOPED_SNAPSHOT_INDEX;
Defensive patterns
Strategy: validation
Validate before calling
let snap_tx = position.transaction_index == BLOCK_SCOPED_SNAPSHOT_INDEX;
let snap_log = position.log_index == BLOCK_SCOPED_SNAPSHOT_INDEX;
if snap_tx != snap_log {
anyhow::bail!("partial snapshot watermark at block {}", position.number);
} Type guard
fn is_consistent_snapshot_marker(position: &PoolStatePosition) -> bool {
(position.transaction_index == BLOCK_SCOPED_SNAPSHOT_INDEX)
== (position.log_index == BLOCK_SCOPED_SNAPSHOT_INDEX)
} Prevention
- Write both sentinel fields together in one statement/transaction.
- Validate snapshot rows at ingest time before persisting.
- Flag partially-set sentinel rows with a data-integrity check.
When it happens
Trigger: During quote validation, position.transaction_index == BLOCK_SCOPED_SNAPSHOT_INDEX differs in truth from position.log_index == BLOCK_SCOPED_SNAPSHOT_INDEX for the pool-state row.
Common situations: A partially applied update that set one sentinel field but not the other; a buggy indexer writing snapshot markers; manual DB edits; schema migration that changed the sentinel encoding for one column only.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Database is not initialized, so we cannot properly bootstrap
- Pool is not initialized and it doesn't contain initial price
- Database is not initialized, so we cannot bootstrap the pool
- cannot advance RPC profiler from block {} to earlier block {
- Outcome side token '{fee_token}' carried a non-zero fee {fee
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/665ba6fa457f03c9.
Report an issue: GitHub.