nautechsystems/nautilus_trader · error · ExecutionIntentReservationError

failed to commit execution intent reservation

Error message

failed to commit execution intent reservation

What it means

This error is raised when transaction.commit() fails while finalizing an execution intent reservation in the blockchain cache database. The adapter wraps the commit error in ExecutionIntentReservationError with stage Commit and the context message "failed to commit execution intent reservation", signaling that the reservation may or may not have been durably persisted (commit outcome is unknown), so callers must treat the reservation state as indeterminate.

Source

Thrown at crates/adapters/blockchain/src/cache/database.rs:5837

                ",
            )
            .bind(row.id)
            .bind(created_block)
            .execute(&mut *transaction)
            .await
            .context("failed to record prepared execution intent")?;

            Ok::<_, anyhow::Error>((transaction, row))
        }
        .await
        .map_err(|source| {
            anyhow::Error::new(ExecutionIntentReservationError {
                stage: ExecutionIntentReservationStage::BeforeCommit,
                source,
            })
        })?;
        transaction.commit().await.map_err(|e| {
            anyhow::Error::new(ExecutionIntentReservationError {
                stage: ExecutionIntentReservationStage::Commit,
                source: anyhow::Error::new(e)
                    .context("failed to commit execution intent reservation"),
            })
        })?;
        Ok(row)
    }

    /// Assigns the signer nonce to a prepared execution intent.
    ///
    /// Repeating the same assignment is idempotent. A different nonce or non-prepared state
    /// fails closed.
    ///
    /// # Errors
    ///
    /// Returns an error if the intent cannot own the nonce or persistence fails.
    pub async fn assign_execution_intent_nonce(
        &self,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the wrapped source for the sqlx commit error to determine if the commit actually landed (query the row by intent key)
  2. Treat reservation state as unknown: reconcile by reading the intents table before retrying
  3. Retry the reservation; if the row already exists, handle the duplicate-key path gracefully
  4. Harden DB connectivity (timeouts, retries, pool limits) to reduce mid-transaction disconnects
  5. Enable statement/slow-query logging on the database to catch commit-time aborts
Defensive patterns

Strategy: try-catch

Validate before calling

// Confirm the row's persisted state after a commit failure before retrying
let existing = sqlx::query("SELECT 1 FROM execution_intents WHERE key = $1")
    .bind(&intent.key)
    .fetch_optional(&pool)
    .await?;

Type guard

fn is_commit_stage(err: &ExecutionIntentReservationError) -> bool {
    matches!(err.stage, ExecutionIntentReservationStage::Commit)
}

Try / catch

match reserve_intent(&pool, intent).await {
    Err(e) if is_commit_stage(&e) => {
        // commit outcome unknown: reconcile by reading the row before retry
        reconcile_or_retry(&pool, intent).await
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling the execution-intent reservation routine and the sqlx transaction commit fails — typically connection drop between the prepared writes and COMMIT, serialization failure, or DB server shutdown.

Common situations: Network blip between app and Postgres at commit time; database failover or restart during the transaction; lock contention causing the commit to be aborted; idle-in-transaction timeout killing the session.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/8e05436417856db6. Report an issue: GitHub.