nautechsystems/nautilus_trader · error · anyhow::Error

Execution payload migration state is missing

Error message

Execution payload migration state is missing

What it means

migrate_execution_payload_batch locks the execution_payload_state row FOR UPDATE and requires it to exist, since migration state (deployment, keys, operation) lives there. A missing row means the store is not in a migration-capable protected state, so the batch step cannot proceed safely.

Source

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

    ) -> anyhow::Result<bool> {
        anyhow::ensure!(
            batch_size > 0,
            "Execution payload batch size must be positive"
        );
        let mut transaction = self
            .pool
            .begin()
            .await
            .context("failed to start execution payload migration 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 migration state")?
        .ok_or_else(|| anyhow::anyhow!("Execution payload migration state is missing"))?;
        let state = execution_payload_state_from_row(&state_row)?;
        validate_execution_payload_state(&state, keys)?;
        anyhow::ensure!(
            state.operation == "migrate",
            "Execution payload storage is {}, not migrating",
            state.operation
        );

        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,
                receipt_success, gas_used, effective_gas_price, current
            FROM execution_transaction_hash
            WHERE payload_expected AND raw_transaction IS NOT NULL
            ORDER BY id
            LIMIT $1

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Activate protected payload storage first (the library's activation path seeds the state row and sets operation='migrate' before migrating)
  2. Verify the state row exists before migrating: SELECT * FROM execution_payload_state WHERE component='signed_transactions'
  3. Check that the migrator's connection string targets the intended database
  4. Restore the state row from a consistent backup if lost

Example fix

// before: migrating an unactivated store
db.migrate_execution_payload_batch(&keys, 500).await?;
// after: ensure activation/protection first
db.require_execution_payload_storage_ready(&keys).await?;
Defensive patterns

Strategy: validation

Validate before calling

let state: Option<(String, String)> = sqlx::query_as(
    "SELECT deployment_id, operation FROM execution_payload_state WHERE component = 'signed_transactions'",
).fetch_optional(&pool).await?;
if state.is_none() {
    anyhow::bail!("activation required before migration");
}

Try / catch

if let Err(e) = db.migrate_execution_payload_batch(&keys, 500).await {
    if e.to_string().contains("migration state is missing") {
        db.require_execution_payload_storage_ready(&keys).await?; // then enter migration properly
    } else { return Err(e); }
}

Prevention

When it happens

Trigger: Calling migrate_execution_payload_batch when execution_payload_state has no row for component 'signed_transactions' — protection never activated, or the state row was deleted/corrupted before migration started.

Common situations: Running the migration tool against a fresh database without activation; restoring a backup without the state row; pointing the migrator at the wrong database/schema.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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