{"record":{"id":"7704165812654471","repo":"nautechsystems/nautilus_trader","slug":"failed-to-commit-execution-transition-e","errorCode":null,"errorMessage":"Failed to commit execution transition: {e}","messagePattern":"Failed to commit execution transition: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":3713,"sourceCode":"            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>> {\n        let chain_id_db = i32::try_from(chain_id)\n            .with_context(|| format!(\"Chain ID {chain_id} exceeds PostgreSQL INTEGER\"))?;\n        sqlx::query_as::<_, ExecutionIntentRow>(\n            \"\n            SELECT","sourceCodeStart":3695,"sourceCodeEnd":3731,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/2114cf6f761429e0adb5ca9596fcd7b895b16011/crates/adapters/blockchain/src/cache/database.rs#L3695-L3731","documentation":"Wrapped sqlx error when transaction.commit() fails at the end of record_execution_status (database.rs:3710-3713). At commit time the work has already executed, so a failure here leaves the outcome ambiguous: the transaction may or may not have durable-committed before the connection died. Because the flow is idempotent (transition_key ON CONFLICT DO NOTHING, COALESCE-guarded hash updates, status re-application is allowed for equal statuses), re-running the same call resolves the ambiguity safely.","triggerScenarios":"Connection dropping exactly at commit; Postgres restarting or being failed over; a serialization failure surfacing at commit; the pool recycling a broken connection under the transaction.","commonSituations":"Network blips between the trading host and Postgres; Postgres maintenance restarts during receipt processing; aggressive idle-in-transaction timeouts killing the session before commit.","solutions":["Treat a commit error as 'outcome unknown' and simply retry record_execution_status with the same arguments - idempotency keys make the replay safe","Check Postgres logs to confirm whether the transaction committed if you need certainty before retrying","If commits fail repeatedly, investigate connection stability (TCP keepalives, PgBouncer transaction pooling vs session state, Postgres restarts)","Avoid wrapping the call in an outer transaction that is itself long-lived; keep begin-to-commit windows short"],"exampleFix":"// before: commit failure is fatal to the watcher loop\nlet _ = db.record_execution_status(intent_id, hash, status, block, block_hash, ok, gas, price).await?;\n\n// after: a failed commit is ambiguous -> replay once and let ON CONFLICT (intent_id, transition_key) dedupe\nmatch db.record_execution_status(intent_id, hash, status, block, block_hash, ok, gas, price).await {\n    Ok(()) => Ok(()),\n    Err(e) if matches!(e.downcast_ref::<sqlx::Error>(), Some(sqlx::Error::Io(_))) => {\n        db.record_execution_status(intent_id, hash, status, block, block_hash, ok, gas, price).await\n    }\n    Err(e) => Err(e),\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":"fn is_commit_ambiguity(err: &anyhow::Error) -> bool {\n    matches!(\n        err.downcast_ref::<sqlx::Error>(),\n        Some(sqlx::Error::Io(_)) | None // None = driver-level disconnect wrappers\n    )\n}","tryCatchPattern":"match db.record_execution_status(...).await {\n    Ok(()) => Ok(()),\n    Err(e) if is_commit_ambiguity(&e) => {\n        // outcome unknown: replay once; transition_key ON CONFLICT dedupes if it committed\n        db.record_execution_status(...).await\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Design every multi-statement cache flow to be replayable (idempotency keys like transition_key) so commit ambiguity is resolved by retry","Enable TCP keepalives and avoid idle-in-transaction downtime between statements and commit","Do not wrap library calls in outer transactions; nested commit paths make ambiguity worse","After repeated commit failures, verify Postgres health before replaying into it"],"tags":["rust","sqlx","postgres","blockchain","commit","idempotency"],"backgroundTag":"db-transaction-commit-failed","analyzedSha":"2114cf6f761429e0adb5ca9596fcd7b895b16011","analyzedAt":"2026-08-21T11:28:30.864Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}