{"record":{"id":"ae217240d817b5dd","repo":"nautechsystems/nautilus_trader","slug":"verified-action-nonce-does-not-match-the-active-in","errorCode":null,"errorMessage":"Verified action nonce does not match the active intent","messagePattern":"Verified action nonce does not match the active intent","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":6101,"sourceCode":"            manifest_version == batch.manifest_version && manifest_digest == batch.manifest_digest,\n            \"Verified action manifest identity changed\"\n        );\n        let intent_nonce = sqlx::query_scalar::<_, Option<i64>>(\n            \"\n            SELECT nonce\n            FROM execution_intent\n            WHERE id = $1 AND chain_id = $2 AND wallet_address = $3 AND active\n            FOR UPDATE\n            \",\n        )\n        .bind(batch.intent_id)\n        .bind(chain_id)\n        .bind(batch.wallet_address)\n        .fetch_optional(&mut *transaction)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to lock intent for verified action: {e}\"))?\n        .ok_or_else(|| anyhow::anyhow!(\"Active verified-action intent was not found\"))?;\n        anyhow::ensure!(\n            intent_nonce == Some(nonce),\n            \"Verified action nonce does not match the active intent\"\n        );\n        let attempt = sqlx::query_scalar::<_, i64>(\n            \"\n            SELECT COUNT(*)\n            FROM execution_verification_decision\n            WHERE intent_id = $1 AND decision_class = $2\n            \",\n        )\n        .bind(batch.intent_id)\n        .bind(batch.decision_class)\n        .fetch_one(&mut *transaction)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to number verified action evidence: {e}\"))?;\n\n        for (index, decision) in batch.decisions.iter().enumerate() {\n            let height_start = decision","sourceCodeStart":6083,"sourceCodeEnd":6119,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/cache/database.rs#L6083-L6119","documentation":"record_execution_verification_batch appends verified-action evidence for an active execution intent. It locks the intent row and compares the batch nonce with the nonce stored on the intent; if they differ, the evidence batch is not authorized for that intent and this ensure! aborts the transaction.","triggerScenarios":"Calling record_execution_verification_batch with an ExecutionVerificationBatch whose `nonce` does not equal the nonce stored in execution_intent for `batch.intent_id` (including when the intent row has a NULL nonce).","commonSituations":"Replaying or reordering batches after a process restart; building the batch from a stale intent record; the intent was replaced/cancelled and re-created with a new nonce; off-by-one or u64/i64 nonce conversion mistakes in the caller.","solutions":["Reload the active intent for intent_id and use its nonce when constructing the ExecutionVerificationBatch","Verify the batch is being applied to the intent created for this nonce; if the intent was superseded, address the replacement scan flow instead","Check that no concurrent writer advanced or reset the intent nonce between batch creation and submission","Inspect execution_intent.nonce in the database and reconcile the caller's nonce ledger"],"exampleFix":"// before\nlet batch = ExecutionVerificationBatch { intent_id, nonce: last_used_nonce, .. };\ndb.record_execution_verification_batch(&batch).await?;\n// after\nlet intent_nonce: Option<i64> = sqlx::query_scalar(\n    \"SELECT nonce FROM execution_intent WHERE id = $1 AND active\",\n).bind(intent_id).fetch_one(&db.pool).await?;\nlet batch = ExecutionVerificationBatch { intent_id, nonce: intent_nonce.expect(\"active intent nonce\") as u64, .. };\ndb.record_execution_verification_batch(&batch).await?;","handlingStrategy":"validation","validationCode":"let intent_nonce: Option<i64> = sqlx::query_scalar(\n    \"SELECT nonce FROM execution_intent WHERE id = $1 AND chain_id = $2 AND wallet_address = $3 AND active\",\n).bind(batch.intent_id).bind(chain_id).bind(batch.wallet_address)\n.fetch_one(&pool).await?;\nif intent_nonce != Some(batch.nonce as i64) {\n    return Err(anyhow::anyhow!(\"skip batch: nonce {batch:?} does not match intent {intent_nonce:?}\"));\n}","typeGuard":"fn nonce_matches(intent_nonce: Option<i64>, batch_nonce: u64) -> bool {\n    i64::try_from(batch_nonce).ok() == intent_nonce\n}","tryCatchPattern":"match db.record_execution_verification_batch(&batch).await {\n    Err(e) if e.to_string().contains(\"nonce does not match\") => {\n        // reload intent, refresh nonce, rebuild batch\n    }\n    Err(e) => return Err(e),\n    Ok(()) => {}\n}","preventionTips":["Always construct batches from a freshly loaded intent row, not cached state","Track nonce progression in one place in the caller","Re-check intent state after process restarts or replays","Never reuse a batch across intent generations"],"tags":["database","nonce","state-mismatch","rust"],"backgroundTag":"invalid-state-transition","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"}