{"record":{"id":"c31128350a52f2ee","repo":"nautechsystems/nautilus_trader","slug":"failed-to-record-verified-finality-transition-e","errorCode":null,"errorMessage":"Failed to record verified finality transition: {e}","messagePattern":"Failed to record verified finality transition: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":7174,"sourceCode":"            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            \",\n        )\n        .bind(finality.intent_id)\n        .bind(finality.transaction_hash)\n        .bind(transition_key)\n        .bind(current_status)\n        .bind(finality.status.as_str())\n        .bind(block_number)\n        .bind(finality.block_hash)\n        .execute(&mut *transaction)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to record verified finality transition: {e}\"))?;\n\n        let nonce_result = sqlx::query(\n            \"\n            UPDATE execution_verification_nonce\n            SET next_canonical_nonce = $3, revision = revision + 1, updated_at = NOW()\n            WHERE chain_id = $1 AND wallet_address = $2\n              AND next_canonical_nonce = $4 AND revision = $5\n            \",\n        )\n        .bind(chain_id)\n        .bind(finality.wallet_address)\n        .bind(next_nonce)\n        .bind(nonce)\n        .bind(revision)\n        .execute(&mut *transaction)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to advance canonical nonce ledger: {e}\"))?;\n        anyhow::ensure!(","sourceCodeStart":7156,"sourceCodeEnd":7192,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/cache/database.rs#L7156-L7192","documentation":"This error wraps any SQLx failure that occurs while inserting a row into the execution_transaction_transition table inside the verified-finality transaction (database.rs:7174). The library throws it because the transition audit row must be recorded atomically with the intent/nonce updates; if the INSERT fails the whole finality transition is rolled back and the caller receives an anyhow error containing the underlying database message.","triggerScenarios":"The INSERT INTO execution_transaction_transition fails: the PostgreSQL connection drops or the statement times out mid-transaction, a constraint is violated (e.g. a foreign key on intent_id/transaction_hash_id or a unique transition_key conflict from re-processing the same finality), or the column types of from_status/to_status/block_number/block_hash do not accept the bound values.","commonSituations":"Database migrations drift behind the deployed code so the transition table or a column is missing; duplicate finality callbacks are replayed for the same (status, tx hash, block) causing a unique-key violation on transition_key; transient connection resets or pool exhaustion under load; a malformed transaction_hash/block_hash whose encoding does not match the column type.","solutions":["Read the wrapped {e} message to identify the root cause (connection error, constraint violation, or undefined table/column).","If it is a unique violation on transition_key, verify the finality event is not being replayed; the transition may already be recorded — check execution_transaction_transition before re-submitting.","If it is a connection/pool error, verify DATABASE_URL connectivity, pool size, and statement timeouts, then retry the whole finality transition (it is transactional and rolls back atomically).","Run pending migrations so execution_transaction_transition exists with the schema this code expects.","Validate the finality payload (block_number within i32/i64 column range, hash encodings) before calling the finality API.","Check Postgres logs for the exact SQLSTATE to distinguish serialization/constraint failures from connectivity failures."],"exampleFix":"// before: retrying single statements independently loses atomicity\nmatch db.record_finality(&finality).await { Err(e) => log::error!(\"{e}\"), ... }\n// after: verify the transition is not already recorded, then retry atomically\nif db.transition_exists(finality.intent_id, &transition_key).await? { return Ok(()); }\ndb.record_verified_finality(&finality).await.context(\"finality transition retry\")?;","handlingStrategy":"try-catch","validationCode":"let exists: bool = sqlx::query_scalar(\n    \"SELECT EXISTS(SELECT 1 FROM execution_transaction_transition WHERE transition_key = $1)\")\n    .bind(&transition_key).fetch_one(&pool).await?;\nif exists { return Ok(()); } // idempotent guard before retrying the transition","typeGuard":"fn is_constraint_violation(e: &anyhow::Error) -> bool {\n    e.chain().any(|c| c.to_string().contains(\"duplicate key\") || c.to_string().contains(\"foreign key\"))\n}","tryCatchPattern":"match db.record_verified_finality(&finality).await {\n    Err(e) if is_constraint_violation(&e) => warn!(\"transition already recorded\"),\n    Err(e) if is_transient(&e) => retry_with_backoff(|| db.record_verified_finality(&finality)),\n    Err(e) => return Err(e),\n    Ok(()) => {}\n}","preventionTips":["Keep database migrations in lockstep with the adapter version before deploying.","Make finality processing idempotent by checking the transition_key first.","Monitor pool health and statement timeouts; alert on connection resets.","Validate block_number and hash encodings against column types before submitting."],"tags":["database","sqlx","transaction","finality"],"backgroundTag":"database-write-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}