nautechsystems/nautilus_trader · error · anyhow::Error
Failed to record verified finality intent: {e}
Error message
Failed to record verified finality intent: {e} What it means
Wraps a sqlx failure on the final UPDATE that records the verified finality state on the intent row (status = finality.status, active flag). This is the last state write of the finality commit; failing it rolls back the entire transaction so headers, verifications, receipt, and hash updates are all discarded. The database error text is embedded via `{e}`.
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:7145
.bind(finality.effective_gas_price)
.execute(&mut *transaction)
.await
.map_err(|e| anyhow::anyhow!("Failed to record verified finality receipt: {e}"))?;
anyhow::ensure!(
hash_result.rows_affected() == 1,
"Finality transaction hash was not found"
);
let active = !fill_emitted && !terminal_emitted;
sqlx::query(
"UPDATE execution_intent SET status = $2, active = $3, updated_at = NOW() WHERE id = $1",
)
.bind(finality.intent_id)
.bind(finality.status.as_str())
.bind(active)
.execute(&mut *transaction)
.await
.map_err(|e| anyhow::anyhow!("Failed to record verified finality intent: {e}"))?;
let transition_key = format!(
"{}:{}:{}:{}",
finality.status.as_str(),
finality.transaction_hash,
finality.block_number,
finality.block_hash
);
sqlx::query(
"
INSERT INTO execution_transaction_transition (
intent_id, transaction_hash_id, transition_key, from_status, to_status,
block_number, block_hash
)
SELECT $1, id, $3, $4, $5, $6, $7
FROM execution_transaction_hash
WHERE intent_id = $1 AND transaction_hash = $2
",View on GitHub (pinned to 18893faf8b)
Solutions
- Read the embedded `{e}` for the exact Postgres error
- If it is a lock timeout, reduce transaction duration or retry finality application with backoff
- Check any CHECK/enum constraints on the status column accept the new status value
- Apply pending migrations so status/active columns match the adapter's expectations
- Verify pool/connectivity health if failures cluster at the end of long transactions
Defensive patterns
Strategy: retry
Validate before calling
// Confirm the status value is acceptable before the final write
let valid = allowed_statuses().contains(&finality.status.as_str().to_string());
if !valid { /* reject earlier, before the transaction begins */ } Try / catch
match result {
Err(e) if is_transient_db_error(&e) || is_lock_timeout(&e) => {
retry_with_backoff(3, || apply_verified_finality(...)).await
}
Err(e) => Err(e),
Ok(v) => Ok(v),
} Prevention
- Keep finality transactions short; do the status UPDATE promptly after the checks
- Align DB CHECK constraints on status with every adapter status change
- Serialize finality per intent to avoid lock contention on the intent row
- Alert on retries clustering at transaction end — a sign of idle-in-transaction timeouts
When it happens
Trigger: The intent-status UPDATE fails: connection loss at the end of a long transaction, lock contention on the intent row, schema drift on status/active columns, or an invalid value for the status enum/text column.
Common situations: Long finality transactions hitting idle-in-transaction timeouts right at the final write; concurrent processors holding a lock on the same intent row; an adapter upgrade adding new status values not accepted by a DB CHECK constraint; pool exhaustion during batch finalization.
Related errors
- Active finality intent was not found
- Failed to persist finality verification: {e}
- Failed to record verified finality transition: {e}
- Implement FromRow for FuturesSpread
- Implement FromRow for OptionSpread
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5773682cf6737fb0.
Report an issue: GitHub.