{"record":{"id":"057df0b81b7c1c7d","repo":"nautechsystems/nautilus_trader","slug":"failed-to-reserve-execution-intent-for-signer-o","errorCode":null,"errorMessage":"Failed to reserve execution intent for signer {} on chain {}: {e}","messagePattern":"Failed to reserve execution intent for signer (.+?) on chain (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":3361,"sourceCode":"        .bind(EXECUTION_SCHEMA_VERSION)\n        .bind(chain_id)\n        .bind(&intent.wallet_address)\n        .bind(&intent.purpose)\n        .bind(&intent.client_order_id)\n        .bind(&intent.trader_id)\n        .bind(&intent.strategy_id)\n        .bind(&intent.account_id)\n        .bind(&intent.instrument_id)\n        .bind(&intent.pool_address)\n        .bind(&intent.transaction_to)\n        .bind(&intent.transaction_input)\n        .bind(&intent.transaction_value)\n        .bind(&intent.amount_in)\n        .bind(created_block)\n        .fetch_one(&mut *transaction)\n        .await\n        .map_err(|e| {\n            anyhow::anyhow!(\n                \"Failed to reserve execution intent for signer {} on chain {}: {e}\",\n                intent.wallet_address,\n                intent.chain_id\n            )\n        })?;\n\n        sqlx::query(\n            \"\n            INSERT INTO execution_transaction_transition (\n                intent_id, transition_key, to_status, block_number\n            ) VALUES ($1, 'prepared', 'prepared', $2)\n            \",\n        )\n        .bind(row.id)\n        .bind(created_block)\n        .execute(&mut *transaction)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to record prepared execution intent: {e}\"))?;","sourceCodeStart":3343,"sourceCodeEnd":3379,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/2114cf6f761429e0adb5ca9596fcd7b895b16011/crates/adapters/blockchain/src/cache/database.rs#L3343-L3379","documentation":"Thrown when the INSERT INTO execution_intent inside reserve_execution_intent fails. The v2 unique partial indexes make ownership conflicts the common cause: another active intent for the same (chain_id, wallet_address) via execution_intent_active_signer_key, or the same client_order_id via execution_intent_client_order_key. It also fires on FK violation when chain_id is absent from the chain table, or CHECK violation when purpose 'swap' lacks client_order_id/trader_id/strategy_id/account_id/instrument_id/pool_address/amount_in.","triggerScenarios":"A second reserve for the same signer while its first intent is still active; retrying a submission with a new client_order_id instead of resuming the original; a swap intent built without full order metadata; a chain_id never registered in the chain table.","commonSituations":"Two executors configured with the same wallet; crash-recovery code that re-reserves rather than resuming; test chains not seeded into the cache.","solutions":["Inspect {e} for the SQLSTATE: 23505 unique violation, 23503 foreign key violation, 23514 check violation, 23502 not null","Complete or release the existing active intent for that signer before reserving again","Reuse the original client_order_id on retries so the conflict is recognized as the same order, not a duplicate","Register the chain row and populate every swap order field (trader/strategy/account/instrument/pool/amount_in) before reserving"],"exampleFix":"// before: reserve blindly on retry\nlet row = db.reserve_execution_intent(&intent).await?;\n\n// after: resume when the signer slot is already owned\nlet active = sqlx::query_scalar::<_, i64>(\n    \"SELECT id FROM execution_intent WHERE chain_id = $1 AND wallet_address = $2 AND active\",\n)\n.bind(chain_id)\n.bind(&intent.wallet_address)\n.fetch_optional(&pool)\n.await?;\nlet row = match active {\n    Some(_) => resume_existing_intent(&db, &intent).await?,\n    None => db.reserve_execution_intent(&intent).await?,\n};","handlingStrategy":"validation","validationCode":"// Check signer-slot and client-order ownership before reserving\nlet conflict: Option<i64> = sqlx::query_scalar(\n    \"SELECT id FROM execution_intent WHERE chain_id = $1 AND wallet_address = $2 AND active\",\n)\n.bind(chain_id)\n.bind(wallet_address)\n.fetch_optional(&pool)\n.await?;\nlet chain_registered: bool = sqlx::query_scalar(\n    \"SELECT EXISTS (SELECT 1 FROM chain WHERE chain_id = $1)\",\n)\n.bind(chain_id)\n.fetch_one(&pool)\n.await?;\nif conflict.is_none() && chain_registered { /* safe to reserve */ }","typeGuard":"fn swap_intent_complete(intent: &ExecutionIntentInsert) -> bool {\n    intent.purpose != \"swap\"\n        || intent.client_order_id.is_some()\n            && intent.trader_id.is_some()\n            && intent.strategy_id.is_some()\n            && intent.account_id.is_some()\n            && intent.instrument_id.is_some()\n            && intent.pool_address.is_some()\n            && intent.amount_in.is_some()\n}","tryCatchPattern":"match db.reserve_execution_intent(&intent).await {\n    Err(e) => {\n        let msg = e.to_string();\n        if msg.contains(\"duplicate key value\") && msg.contains(\"execution_intent_active_signer_key\") {\n            // signer slot owned: load and resume the existing active intent\n        } else if msg.contains(\"duplicate key value\") && msg.contains(\"execution_intent_client_order_key\") {\n            // same client order already reserved: treat as duplicate submission, resume it\n        } else if msg.contains(\"violates foreign key constraint\") {\n            // register the chain row first\n        } else {\n            return Err(e);\n        }\n    }\n    Ok(row) => { /* proceed to nonce assignment */ }\n}","preventionTips":["Use one wallet per executor process so the active-signer unique index never conflicts","Derive client_order_id deterministically so retries collide with the original reservation instead of creating duplicates","Register chains in the cache before enabling execution on them","Validate swap intents carry all order metadata before reserving"],"tags":["rust","sqlx","postgresql","unique-constraint","foreign-key","execution-intent","idempotency"],"backgroundTag":"postgres-unique-constraint-violation","analyzedSha":"2114cf6f761429e0adb5ca9596fcd7b895b16011","analyzedAt":"2026-08-21T11:28:30.864Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}