{"record":{"id":"8f560cf1734af062","repo":"nautechsystems/nautilus_trader","slug":"execution-intent-is-not-prepared-for-canonical","errorCode":null,"errorMessage":"Execution intent {} is not prepared for canonical nonce {}","messagePattern":"Execution intent (.+?) is not prepared for canonical nonce (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":6030,"sourceCode":"            .map_err(|e| anyhow::anyhow!(\"Failed to persist pre-sign verification: {e}\"))?;\n        }\n\n        let result = sqlx::query(\n            \"\n            UPDATE execution_intent\n            SET nonce = $2, updated_at = NOW()\n            WHERE id = $1\n              AND status = 'prepared'\n              AND active\n              AND (nonce IS NULL OR nonce = $2)\n            \",\n        )\n        .bind(assignment.intent_id)\n        .bind(nonce)\n        .execute(&mut *transaction)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to assign verified execution nonce: {e}\"))?;\n        anyhow::ensure!(\n            result.rows_affected() == 1,\n            \"Execution intent {} is not prepared for canonical nonce {}\",\n            assignment.intent_id,\n            assignment.nonce\n        );\n        transaction\n            .commit()\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to commit verified nonce assignment: {e}\"))?;\n        Ok(())\n    }\n\n    /// Appends one verified decision batch before an action on an existing active intent.\n    pub(crate) async fn record_execution_verification_batch(\n        &self,\n        batch: &ExecutionVerificationBatch<'_>,\n    ) -> anyhow::Result<()> {\n        anyhow::ensure!(","sourceCodeStart":6012,"sourceCodeEnd":6048,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/cache/database.rs#L6012-L6048","documentation":"This error is thrown when an UPDATE that assigns a verified execution nonce to an execution intent affects zero rows. It means the intent row with that ID does not exist in a state that can accept the canonical nonce (e.g. missing or already finalized), so the transaction is aborted via anyhow::ensure!.","triggerScenarios":"Calling the nonce-assignment routine with an intent_id that has no matching prepared execution intent row, or an intent that is no longer in the preparable state when the canonical nonce UPDATE runs.","commonSituations":"Replaying a nonce assignment after the intent was already processed; a race where another worker consumed or finalized the intent; passing an intent_id from a different database or environment; stale orchestration state after a deploy.","solutions":["Verify the intent_id exists and is in the prepared state before requesting nonce assignment (query the execution intent table).","Check for concurrent workers assigning nonces to the same intent and add locking or a queue so only one assigner runs.","Re-fetch fresh intent state from this database rather than reusing cached IDs from a previous run or environment.","Inspect the UPDATE's WHERE clause and bindings (intent_id, nonce) to confirm they match the actual row values."],"exampleFix":"// before: assign nonce for a stale id\nassign_verified_execution_nonce(&pool, &Assignment { intent_id: stale_id, nonce }).await?;\n// after: confirm the intent is still prepared first\nlet prepared = sqlx::query_scalar::<_, i64>(\"SELECT 1 FROM execution_intent WHERE intent_id = $1 AND status = 'prepared'\")\n    .bind(&stale_id).fetch_optional(&pool).await?;\nanyhow::ensure!(prepared.is_some(), \"intent {stale_id} not prepared\");\nassign_verified_execution_nonce(&pool, &Assignment { intent_id: stale_id, nonce }).await?;","handlingStrategy":"validation","validationCode":"// Rust: confirm the intent is prepared before assignment\nlet prepared = sqlx::query_scalar::<_, i64>(\n    \"SELECT 1 FROM execution_intent WHERE intent_id = $1 AND status = 'prepared'\")\n    .bind(&assignment.intent_id)\n    .fetch_optional(&pool).await?;\nanyhow::ensure!(prepared.is_some(), \"intent {} not prepared\", assignment.intent_id);","typeGuard":"fn is_prepared(status: &str) -> bool { status.eq_ignore_ascii_case(\"prepared\") }","tryCatchPattern":null,"preventionTips":["Single-writer discipline: only one worker assigns nonces per intent.","Re-read intent state from the database immediately before assignment.","Alert on rows_affected == 0 to catch races early."],"tags":["database","nonce","concurrency","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"}