nautechsystems/nautilus_trader · error · anyhow::Error

Execution payload rewrap state is missing

Error message

Execution payload rewrap state is missing

What it means

During execution-payload key rewrapping, `rewrap_execution_payload_batch` locks and reads the singleton `execution_payload_state` row for component 'signed_transactions' (`SELECT ... FOR UPDATE`). This error is raised when that row does not exist. The library requires the state row to have been initialized by `begin_execution_payload_rewrap` (or equivalent setup) before batch rewrapping can proceed, since it tracks the operation ('ready'/'rewrap') and active key ID in it.

Source

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

    async fn rewrap_execution_payload_batch(
        &self,
        keys: &PayloadKeySet,
        batch_size: i64,
    ) -> anyhow::Result<bool> {
        let mut transaction = self
            .pool
            .begin()
            .await
            .context("failed to start execution payload rewrap batch")?;
        lock_execution_payload_operation(&mut transaction).await?;
        let state_row = sqlx::query(
            "SELECT deployment_id, protocol_version, operation, active_key_id \
             FROM execution_payload_state WHERE component = 'signed_transactions' FOR UPDATE",
        )
        .fetch_optional(&mut *transaction)
        .await
        .context("failed to lock execution payload rewrap state")?
        .ok_or_else(|| anyhow::anyhow!("Execution payload rewrap state is missing"))?;
        let state = execution_payload_state_from_row(&state_row)?;
        validate_execution_payload_state(&state, keys)?;
        if state.operation == "ready" {
            transaction
                .commit()
                .await
                .context("failed to complete execution payload rewrap")?;
            return Ok(true);
        }
        anyhow::ensure!(
            state.operation == "rewrap",
            "Execution payload storage is not rewrapping"
        );
        let rows = sqlx::query_as::<_, ExecutionTransactionHashRow>(
            "
            SELECT
                id, intent_id, chain_id, transaction_hash, payload_expected,
                raw_transaction, sealed_transaction, status, block_number, block_hash,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Run the database initialization/migration path that inserts the `execution_payload_state` row for component 'signed_transactions' (via `begin_execution_payload_rewrap` or the schema bootstrap) before starting the rewrap.
  2. Check that the adapter is connecting to the intended database/schema — a wrong DATABASE_URL can point at an uninitialized database.
  3. If the row was deleted accidentally, insert it manually with deployment_id/protocol_version matching the configured key set, operation='ready', and the current active_key_id.
  4. Verify schema version: apply any pending migrations so the `execution_payload_state` table and its seed row exist.

Example fix

// before: rewrap called directly on an uninitialized DB
rewrap_execution_payload_batch(&keys, batch_size).await?;
// after: ensure state is initialized first (inserts the state row if absent)
begin_execution_payload_rewrap(&keys).await?;
rewrap_execution_payload_batch(&keys, batch_size).await?;
Defensive patterns

Strategy: validation

Validate before calling

let state = sqlx::query("SELECT deployment_id, protocol_version, operation, active_key_id FROM execution_payload_state WHERE component = 'signed_transactions'")
    .fetch_optional(&mut *tx).await?;
if state.is_none() {
    // initialize via begin_execution_payload_rewrap / schema bootstrap before proceeding
    return Err(anyhow!("execution_payload_state row missing; run initialization first"));
}

Prevention

When it happens

Trigger: Calling the rewrap flow (which invokes `rewrap_execution_payload_batch`) against a database where `execution_payload_state` has no row with component='signed_transactions' — e.g. a freshly provisioned database whose migration/initialization step was skipped, or a row deleted manually or by a partial migration.

Common situations: Pointing the adapter at an empty/new Postgres schema created without running the execution-payload state initialization; restoring a partial backup that omitted the state table's row; manual SQL cleanup that deleted the bookkeeping row; running a newer adapter version against an old database that predates the `execution_payload_state` table.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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