nautechsystems/nautilus_trader · error · anyhow::Error
Failed to record execution transition: {e}
Error message
Failed to record execution transition: {e} What it means
Wrapped sqlx error from the INSERT INTO execution_transaction_transition ... SELECT ... FROM execution_transaction_hash ... ON CONFLICT (intent_id, transition_key) DO NOTHING statement in record_execution_status (database.rs:3687-3708). This appends the audit row for the observed transition; the ON CONFLICT clause makes repeated observations of the same (status, hash, block) idempotent, so a unique violation on that key is impossible - the error is another database-level fault.
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:3708
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
ON CONFLICT (intent_id, transition_key) DO NOTHING
",
)
.bind(intent_id)
.bind(transaction_hash)
.bind(transition_key)
.bind(current_status)
.bind(status.as_str())
.bind(block_number_db)
.bind(block_hash)
.execute(&mut *transaction)
.await
.map_err(|e| anyhow::anyhow!("Failed to record execution transition: {e}"))?;
transaction
.commit()
.await
.map_err(|e| anyhow::anyhow!("Failed to commit execution transition: {e}"))?;
Ok(())
}
/// Loads the active intent owned by a signer, if one exists.
///
/// # Errors
///
/// Returns an error if the query fails.
pub async fn get_active_execution_intent(
&self,
chain_id: u32,
wallet_address: &str,
) -> anyhow::Result<Option<ExecutionIntentRow>> {View on GitHub (pinned to 2114cf6f76)
Solutions
- Inspect the {e} root cause via downcast to sqlx::Error to see whether it is a connection, FK, or constraint failure
- Verify the execution_transaction_transition table exists with the expected columns by running the project migrations
- Retry the entire record_execution_status call for transient causes; the transaction rolled back and the transition_key deduplication keeps the retry safe
- If a length constraint is reported for transition_key, widen the column in a migration rather than truncating keys (they encode reorg identity)
Defensive patterns
Strategy: retry
Type guard
fn is_transient_db_error(err: &anyhow::Error) -> bool {
err.downcast_ref::<sqlx::Error>().map_or(false, |e| {
matches!(e, sqlx::Error::PoolTimedOut | sqlx::Error::PoolClosed | sqlx::Error::Io(_))
|| e.as_database_error().and_then(|d| d.code()).map_or(false, |c| {
matches!(c.as_ref(), "40001" | "40P01" | "55P03" | "57014" | "08000" | "08003" | "08006")
})
})
} Try / catch
match db.record_execution_status(...).await {
Ok(()) => {}
Err(e) if is_transient_db_error(&e) => retry_with_backoff(e),
Err(e) => return Err(e),
} Prevention
- Size transition_key columns for the full status:hash:block_number:block_hash composite in migrations
- Never delete execution_transaction_hash rows for intents still receiving observations (FK integrity of the audit insert)
- Apply transition-table migrations together with the intent/hash schema changes
When it happens
Trigger: Connection loss or timeout while inserting the transition row; a foreign-key violation if transaction_hash_id cannot be resolved (the inner SELECT reads the hash row in the same transaction, so this implies the hash UPDATE in error 81 did not commit); a column-length or CHECK violation if transition_key or from_status/to_status exceed their column definitions after schema drift.
Common situations: Long transition_key strings (status:hash:block_number:block_hash) overflowing a VARCHAR-limited transition_key column on older schemas; Postgres failover between the hash UPDATE and this insert; migrations adding the transition table never applied.
Related errors
- Failed to record replacement transition: {e}
- Failed to update execution hash {transaction_hash}: {e}
- Failed to update execution intent {intent_id}: {e}
- Failed to start replacement transaction persistence: {e}
- Failed to retire replaced execution hash: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/50d3c5a7aaac92d0.
Report an issue: GitHub.