{"record":{"id":"50d3c5a7aaac92d0","repo":"nautechsystems/nautilus_trader","slug":"failed-to-record-execution-transition-e","errorCode":null,"errorMessage":"Failed to record execution transition: {e}","messagePattern":"Failed to record execution transition: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":3708,"sourceCode":"                intent_id, transaction_hash_id, transition_key, from_status, to_status,\n                block_number, block_hash\n            )\n            SELECT $1, id, $3, $4, $5, $6, $7\n            FROM execution_transaction_hash\n            WHERE intent_id = $1 AND transaction_hash = $2\n            ON CONFLICT (intent_id, transition_key) DO NOTHING\n            \",\n        )\n        .bind(intent_id)\n        .bind(transaction_hash)\n        .bind(transition_key)\n        .bind(current_status)\n        .bind(status.as_str())\n        .bind(block_number_db)\n        .bind(block_hash)\n        .execute(&mut *transaction)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to record execution transition: {e}\"))?;\n\n        transaction\n            .commit()\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to commit execution transition: {e}\"))?;\n        Ok(())\n    }\n\n    /// Loads the active intent owned by a signer, if one exists.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the query fails.\n    pub async fn get_active_execution_intent(\n        &self,\n        chain_id: u32,\n        wallet_address: &str,\n    ) -> anyhow::Result<Option<ExecutionIntentRow>> {","sourceCodeStart":3690,"sourceCodeEnd":3726,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/2114cf6f761429e0adb5ca9596fcd7b895b16011/crates/adapters/blockchain/src/cache/database.rs#L3690-L3726","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"fn is_transient_db_error(err: &anyhow::Error) -> bool {\n    err.downcast_ref::<sqlx::Error>().map_or(false, |e| {\n        matches!(e, sqlx::Error::PoolTimedOut | sqlx::Error::PoolClosed | sqlx::Error::Io(_))\n            || e.as_database_error().and_then(|d| d.code()).map_or(false, |c| {\n                matches!(c.as_ref(), \"40001\" | \"40P01\" | \"55P03\" | \"57014\" | \"08000\" | \"08003\" | \"08006\")\n            })\n    })\n}","tryCatchPattern":"match db.record_execution_status(...).await {\n    Ok(()) => {}\n    Err(e) if is_transient_db_error(&e) => retry_with_backoff(e),\n    Err(e) => return Err(e),\n}","preventionTips":["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"],"tags":["rust","sqlx","postgres","blockchain","audit-log","transaction"],"backgroundTag":"database-insert-failed","analyzedSha":"2114cf6f761429e0adb5ca9596fcd7b895b16011","analyzedAt":"2026-08-21T11:28:30.864Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}