nautechsystems/nautilus_trader · error · anyhow::Error

Failed to load from execution_transaction table: {e}

Error message

Failed to load from execution_transaction table: {e}

What it means

This error wraps any SQLx failure that occurs while fetching a row from the `execution_transaction` table via `fetch_optional`. The database lookup itself failed (as opposed to simply returning no row), so the error carries the underlying SQLx/Postgres message. It signals a broken query rather than a missing record.

Source

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

                    wallet_address,
                    nonce,
                    transaction_hash,
                    purpose,
                    status,
                    client_order_id,
                    1 AS source_priority
                FROM execution_transaction
                WHERE chain_id = $1 AND transaction_hash = $2
            ) AS record
            ORDER BY source_priority
            LIMIT 1
        ",
        )
        .bind(chain_id_db)
        .bind(transaction_hash)
        .fetch_optional(&self.pool)
        .await
        .map_err(|e| anyhow::anyhow!("Failed to load from execution_transaction table: {e}"))
    }
}

fn execution_payload_state_from_row(
    row: &sqlx::postgres::PgRow,
) -> anyhow::Result<ExecutionPayloadState> {
    Ok(ExecutionPayloadState {
        deployment_id: row.try_get("deployment_id")?,
        protocol_version: row.try_get("protocol_version")?,
        operation: row.try_get("operation")?,
        active_key_id: row.try_get("active_key_id")?,
    })
}

fn validate_execution_payload_state(
    state: &ExecutionPayloadState,
    keys: &PayloadKeySet,
) -> anyhow::Result<()> {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the wrapped SQLx error message to identify the concrete DB failure (connection, missing table, timeout)
  2. Run pending database migrations to ensure execution_transaction exists
  3. Check database connectivity and that DATABASE_URL points to the correct instance
  4. Inspect pool configuration; increase pool size/timeout if errors appear under load
Defensive patterns

Strategy: retry

Validate before calling

sqlx::query("SELECT 1 FROM execution_transaction LIMIT 1").fetch_optional(&pool).await.map_err(|e| format!("db unreachable: {e}"))?;

Try / catch

match load_execution_transaction(&pool, chain_id, &hash).await {
    Ok(Some(state)) => handle(state),
    Ok(None) => handle_missing(),
    Err(e) if is_transient_db_error(&e) => schedule_retry(e),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling the execution_transaction load method when the database is unreachable, the table does not exist, credentials are wrong, the connection pool is exhausted, or the query type mismatch (e.g. a binary/hash column with wrong bind type) causes a Postgres error.

Common situations: Postgres restarted or network drop mid-operation; migrations not applied so execution_transaction table is missing; wrong DATABASE_URL pointing to a schema without the table; pool timeout under load.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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