nautechsystems/nautilus_trader · error · anyhow::Error
Failed to update execution_transaction table: {e}
Error message
Failed to update execution_transaction table: {e} What it means
This wraps SQLx failures from the UPDATE of execution_transaction that sets a transaction's status by hash (database.rs:7409). The library throws it when the statement fails at the database level; a zero-row update is reported separately by the ensure! that follows, so this error is strictly a query-execution failure.
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:7409
pub async fn update_execution_transaction_status(
&self,
chain_id: u32,
transaction_hash: &str,
status: &str,
) -> anyhow::Result<()> {
let result = sqlx::query(
"
UPDATE execution_transaction
SET status = $3
WHERE chain_id = $1 AND transaction_hash = $2
",
)
.bind(chain_id as i32)
.bind(transaction_hash)
.bind(status)
.execute(&self.pool)
.await
.map_err(|e| anyhow::anyhow!("Failed to update execution_transaction table: {e}"))?;
anyhow::ensure!(
result.rows_affected() == 1,
"Execution transaction {transaction_hash} was not found for status update"
);
Ok(())
}
/// Loads an execution transaction record by chain ID and transaction hash.
///
/// # Errors
///
/// Returns an error if the database operation fails.
pub async fn get_execution_transaction(
&self,
chain_id: u32,
transaction_hash: &str,
) -> anyhow::Result<Option<ExecutionTransactionRow>> {View on GitHub (pinned to 18893faf8b)
Solutions
- Read the wrapped {e} to identify the root cause (connection, constraint, undefined column).
- Apply pending migrations so execution_transaction matches the expected schema.
- Validate transaction_hash format and status value fit the column types before the update.
- Retry on transient connection/timeout errors; the update is idempotent for the same status.
- Check Postgres logs for lock timeouts and reduce contention with concurrent writers.
Example fix
// before: losing the cause by ignoring the error
let _ = db.update_execution_transaction_status(chain_id, &hash, status).await;
// after: surface and retry transient failures
retry(3, backoff, || db.update_execution_transaction_status(chain_id, &hash, status))
.await.with_context(|| format!("status update for {hash}"))?; Defensive patterns
Strategy: retry
Validate before calling
let valid = transaction_hash.len() >= 64 && status.len() <= MAX_STATUS_LEN;
anyhow::ensure!(valid, "malformed transaction_hash or status for execution_transaction update");
let exists: Option<i32> = sqlx::query_scalar(
"SELECT 1 FROM execution_transaction WHERE chain_id = $1 AND transaction_hash = $2")
.bind(chain_id).bind(transaction_hash).fetch_optional(&pool).await?; Type guard
fn is_transient_update_error(e: &anyhow::Error) -> bool {
let s = e.to_string();
s.contains("connection") || s.contains("timed out") || s.contains("deadlock")
} Try / catch
match update_result {
Err(e) if is_transient_update_error(&e) => retry_with_backoff(|| update_status(chain_id, hash, status)).await?,
Err(e) => return Err(e),
Ok(()) => {}
} Prevention
- Apply migrations before deploy so execution_transaction schema matches code.
- Validate hash length/encoding and status enum against column constraints before updating.
- Retry transient failures; the same-status update is idempotent.
- Monitor lock contention on execution_transaction and stagger concurrent updates.
When it happens
Trigger: The UPDATE execution_transaction SET status = $3 WHERE chain_id = $1 AND transaction_hash = $2 fails: connection loss or statement timeout, missing/altered columns from migration drift, value out of range for the status or hash column types, or lock contention until timeout.
Common situations: Adapter schema behind applied code version; Postgres connectivity issues during status updates; extremely long hash strings or unexpected status values failing column constraints; concurrent writers holding locks on the execution_transaction row.
Related errors
- Implement FromRow for FuturesSpread
- Implement FromRow for OptionSpread
- Failed to load account events: {e}
- Failed to seed chain table: {e}
- Failed to call create_block_partition for chain {}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/c63010fae9814fa5.
Report an issue: GitHub.