{"record":{"id":"0b078a5c16d42d7a","repo":"nautechsystems/nautilus_trader","slug":"failed-to-update-execution-intent-intent-id-e","errorCode":null,"errorMessage":"Failed to update execution intent {intent_id}: {e}","messagePattern":"Failed to update execution intent (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":3679,"sourceCode":"        .map_err(|e| anyhow::anyhow!(\"Failed to update execution hash {transaction_hash}: {e}\"))?;\n        anyhow::ensure!(\n            hash_result.rows_affected() == 1,\n            \"Execution transaction hash {transaction_hash} was not found for intent {intent_id}\"\n        );\n\n        sqlx::query(\n            \"\n            UPDATE execution_intent\n            SET status = $2, active = $3, updated_at = NOW()\n            WHERE id = $1\n            \",\n        )\n        .bind(intent_id)\n        .bind(status.as_str())\n        .bind(active)\n        .execute(&mut *transaction)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to update execution intent {intent_id}: {e}\"))?;\n\n        let transition_key = format!(\n            \"{}:{transaction_hash}:{}:{}\",\n            status.as_str(),\n            block_number.map_or_else(|| \"none\".to_string(), |value| value.to_string()),\n            block_hash.unwrap_or(\"none\")\n        );\n        sqlx::query(\n            \"\n            INSERT INTO execution_transaction_transition (\n                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            \",","sourceCodeStart":3661,"sourceCodeEnd":3697,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/2114cf6f761429e0adb5ca9596fcd7b895b16011/crates/adapters/blockchain/src/cache/database.rs#L3661-L3697","documentation":"Wrapped sqlx error from the UPDATE execution_intent SET status = $2, active = $3 statement in record_execution_status (database.rs:3667-3679), which advances the intent's status and computes the active flag after a receipt observation. The row was already locked FOR UPDATE earlier in the same transaction, so lock contention on this specific statement is unlikely; failures are typically connection loss, statement timeout, or a constraint violation on the status/active columns.","triggerScenarios":"The database connection dying between the hash UPDATE and the intent UPDATE; a CHECK constraint on execution_intent.status rejecting the bound status string; schema drift where the active or updated_at column is missing; a serialization failure aborting the transaction at this point.","commonSituations":"Postgres restart or failover mid-transaction; running against a schema from an older migration set that lacks the active column; a status enum/domain on the column that does not include the value being written.","solutions":["Read the {e} cause: downcast to sqlx::Error and inspect as_database_error() for the failing constraint or SQLSTATE","Apply pending migrations so execution_intent matches the status/active/updated_at columns","Retry the whole call on transient classes (connection, 40001/40P01/57014); the enclosing transaction rolled back so the retry is idempotent","If a CHECK/domain constraint rejected the status string, fix the TransactionStatus value being passed at the call site"],"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), // rollback makes replay safe\n    Err(e) => return Err(e),\n}","preventionTips":["Keep execution_intent migrations current, especially status CHECK constraints and the active column","Use the typed TransactionStatus enum end-to-end instead of ad-hoc strings so only valid statuses reach the UPDATE","Short transactions reduce the window where this statement can be killed by a failover"],"tags":["rust","sqlx","postgres","blockchain","intent","transaction"],"backgroundTag":"database-update-failed","analyzedSha":"2114cf6f761429e0adb5ca9596fcd7b895b16011","analyzedAt":"2026-08-21T11:28:30.864Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}