{"record":{"id":"0e4486cf81afcb16","repo":"nautechsystems/nautilus_trader","slug":"failed-to-lock-execution-intent-intent-id-e","errorCode":null,"errorMessage":"Failed to lock execution intent {intent_id}: {e}","messagePattern":"Failed to lock execution intent (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":3623,"sourceCode":"        let gas_used_db = gas_used.map(i64::try_from).transpose().with_context(|| {\n            format!(\n                \"Execution gas used {} exceeds PostgreSQL BIGINT\",\n                gas_used.unwrap_or_default()\n            )\n        })?;\n        let mut transaction = self\n            .pool\n            .begin()\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to start execution status transition: {e}\"))?;\n        let (current_status, fill_emitted, terminal_emitted) =\n            sqlx::query_as::<_, (String, bool, bool)>(\n            \"SELECT status, fill_emitted, terminal_emitted FROM execution_intent WHERE id = $1 FOR UPDATE\",\n        )\n        .bind(intent_id)\n        .fetch_optional(&mut *transaction)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to lock execution intent {intent_id}: {e}\"))?\n        .ok_or_else(|| anyhow::anyhow!(\"Execution intent {intent_id} was not found\"))?;\n        anyhow::ensure!(\n            execution_transition_allowed(&current_status, status),\n            \"Invalid execution transition for intent {intent_id}: {current_status} -> {}\",\n            status.as_str()\n        );\n\n        let active = match status {\n            TransactionStatus::Finalized | TransactionStatus::Reverted => {\n                !fill_emitted && !terminal_emitted\n            }\n            TransactionStatus::Recoverable => false,\n            _ => true,\n        };\n        let hash_result = sqlx::query(\n            \"\n            UPDATE execution_transaction_hash\n            SET status = $3,","sourceCodeStart":3605,"sourceCodeEnd":3641,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/2114cf6f761429e0adb5ca9596fcd7b895b16011/crates/adapters/blockchain/src/cache/database.rs#L3605-L3641","documentation":"Thrown when the SELECT status, fill_emitted, terminal_emitted ... FOR UPDATE that locks the intent inside record_execution_status fails. This is the hot receipt path's serialization point, so the wrapped error is typically 'lock timeout' or 'deadlock detected' against other transition writers, or a dropped connection.","triggerScenarios":"Two observers recording statuses for the same intent simultaneously; lock_timeout exceeded against a long-running transition; connection drop while waiting for the row lock.","commonSituations":"Multiple watchers (confirmations, reorg monitors, replacement pollers) racing on one intent; deadlock-prone lock orderings across intents.","solutions":["Retry with backoff on lock timeout or deadlock - both are transient for this access pattern","Funnel status observations for one intent through a single ordered task (e.g. keyed by intent_id)","Raise lock_timeout modestly if confirmation bursts regularly exceed it"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt in 0..3 {\n    match db.record_execution_status(intent_id, &tx_hash, status, block, hash, success, gas, price).await {\n        Ok(()) => break,\n        Err(e) => {\n            let msg = e.to_string();\n            if msg.contains(\"lock timeout\") || msg.contains(\"deadlock detected\") {\n                tokio::time::sleep(Duration::from_millis(50u64 << attempt)).await;\n                continue;\n            }\n            return Err(e);\n        }\n    }\n}","preventionTips":["Route all status observations for a given intent through one ordered queue (key by intent_id)","Acquire intent locks in a consistent order when a task touches multiple intents","Retry deadlocks automatically - Postgres aborts only one side and the operation is idempotent"],"tags":["rust","sqlx","postgresql","row-lock","deadlock","status-transition"],"backgroundTag":"database-query-failed","analyzedSha":"2114cf6f761429e0adb5ca9596fcd7b895b16011","analyzedAt":"2026-08-21T11:28:30.864Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}