nautechsystems/nautilus_trader · error · anyhow::Error
Failed to assign nonce
Error message
Failed to assign nonce {nonce} to execution intent: {e} What it means
This error is returned by the nonce-assignment database method when the SQL UPDATE that binds a nonce to a prepared execution intent fails at the query level. The anyhow error wraps the underlying sqlx error, so the original cause (connection failure, constraint violation, query error) is embedded in the message. It indicates persistence of the nonce-to-intent mapping could not be completed.
Solutions
- Inspect the wrapped sqlx error in the message to identify the root cause (connection vs constraint vs type).
- Verify the database is reachable and the pool is healthy (check connection limits, TLS, credentials).
- Confirm the execution_intents table schema matches what the query expects (column names and types, especially the nonce column).
- Retry the assignment after recovering connectivity; the operation is idempotent as long as the intent is still unassigned.
Example fix
// before: no diagnostics around the call
database.assign_execution_intent_nonce(&intent_id, nonce).await?;
// after: surface the wrapped cause and retry transient failures
match database.assign_execution_intent_nonce(&intent_id, nonce).await {
Err(e) if is_transient(&e) => { backoff_retry(|| database.assign_execution_intent_nonce(&intent_id, nonce)).await?; }
Err(e) => { tracing::error!(%nonce, error = %e, "nonce assignment failed"); return Err(e); }
Ok(()) => {}
} Defensive patterns
Strategy: try-catch
Validate before calling
// before calling, confirm DB connectivity and intent existence
let reachable = sqlx::query("SELECT 1").execute(&pool).await.is_ok();
let prepared = sqlx::query("SELECT 1 FROM execution_intents WHERE intent_id = $1 AND nonce IS NULL")
.bind(intent_id).fetch_optional(&pool).await?.is_some(); Try / catch
match database.assign_execution_intent_nonce(&intent_id, nonce).await {
Ok(()) => {},
Err(e) if e.to_string().contains("Failed to assign nonce") => {
tracing::error!(%nonce, error = %e, "nonce assignment write failed");
if is_transient(&e) { retry_with_backoff(...).await?; } else { return Err(e); }
}
Err(e) => return Err(e),
} Prevention
- Monitor database connectivity and pool health before the assignment flow starts.
- Keep the intents table schema and migrations in sync with the query expectations.
- Use connection retries/timeouts on the sqlx pool.
- Run assignment inside the same transaction/session as intent preparation where possible.
When it happens
Trigger: Calling assign_execution_intent_nonce (database.rs ~5874) when the UPDATE ... SET nonce = $ WHERE intent_id = $ query returns an Err: PostgreSQL connection failure, SQL syntax/type error, transaction aborted, or a database constraint violation during the bind/execute.
Common situations: Database connectivity loss between intent preparation and nonce assignment; the pool being closed or saturated; a schema migration changing the execution intents table columns/types; i32 overflow converting nonce_db; concurrent transactions aborting the update.
Related errors
- Failed to insert into position_event table
- Failed to batch insert into block table
- Failed to batch insert into pool_event_block table
- Failed to batch insert into pool_fee_collect table
- Failed to batch insert into pool_fee_protocol_collect_event…
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b5ba6cdf092f0ef8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/blockchain/src/cache/database.rs:5874
intent_id: i64,
nonce: u64,
) -> anyhow::Result<()> {
let nonce_db = i64::try_from(nonce)
.with_context(|| format!("Execution nonce {nonce} exceeds PostgreSQL BIGINT"))?;
let result = sqlx::query(
"
UPDATE execution_intent
SET nonce = $2, updated_at = NOW()
WHERE id = $1
AND status = 'prepared'
AND (nonce IS NULL OR nonce = $2)
",
)
.bind(intent_id)
.bind(nonce_db)
.execute(&self.pool)
.await
.map_err(|e| anyhow::anyhow!("Failed to assign nonce {nonce} to execution intent: {e}"))?;
anyhow::ensure!(
result.rows_affected() == 1,
"Execution intent {intent_id} is not prepared for nonce {nonce}"
);
Ok(())
}
/// Assigns the canonical nonce and its authorizing verification evidence atomically.
///
/// # Errors
///
/// Returns an error if the durable nonce ledger, intent ownership, manifest identity, or
/// evidence is inconsistent, or if persistence fails.
pub(crate) async fn assign_execution_intent_nonce_verified(
&self,
assignment: &ExecutionNonceAssignment<'_>,
) -> anyhow::Result<()> {
anyhow::ensure!(View on GitHub (pinned to 18893faf8b)