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
- Read the wrapped SQLx error message to identify the concrete DB failure (connection, missing table, timeout)
- Run pending database migrations to ensure execution_transaction exists
- Check database connectivity and that DATABASE_URL points to the correct instance
- 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
- Run migrations at startup so the table always exists
- Add connection-pool health checks and retry with backoff for transient Postgres errors
- Validate DATABASE_URL and credentials in a startup health check
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
- Failed to load instruments: {e}
- Failed to insert instrument close: {e}
- Failed to load instrument closes: {e}
- Failed to insert into trader table: {e}
- Failed to insert into order table: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/9e37baf587af2f66.
Report an issue: GitHub.