nautechsystems/nautilus_trader · error

Failed to load trades: {e}

Error message

Failed to load trades: {e}

What it means

This error wraps sqlx failures from `SELECT * FROM "trade" WHERE instrument_id = $1 ORDER BY ts_event ASC` in `load_trades`. It signals the trade rows could not be fetched from PostgreSQL; the raw sqlx error is embedded in the message.

Source

Thrown at crates/infrastructure/src/sql/queries.rs:1282

    }

    /// Loads all `TradeTick` entries for `instrument_id` via the provided `pool`.
    ///
    /// # Errors
    ///
    /// Returns an error if the SQL SELECT or deserialization fails.
    pub async fn load_trades(
        pool: &PgPool,
        instrument_id: &InstrumentId,
    ) -> anyhow::Result<Vec<TradeTick>> {
        sqlx::query_as::<_, TradeTickRow>(
            r#"SELECT * FROM "trade" WHERE instrument_id = $1 ORDER BY ts_event ASC"#,
        )
        .bind(instrument_id.to_string())
        .fetch_all(pool)
        .await
        .map(|rows| rows.into_iter().map(|row| row.0).collect())
        .map_err(|e| anyhow::anyhow!("Failed to load trades: {e}"))
    }

    /// Inserts a `QuoteTick` entry via the provided `pool`.
    ///
    /// # Errors
    ///
    /// Returns an error if the SQL INSERT operation fails.
    pub async fn add_quote(pool: &PgPool, quote: &QuoteTick) -> anyhow::Result<()> {
        sqlx::query(r#"
            INSERT INTO "quote" (
                instrument_id, bid_price, ask_price, bid_size, ask_size, ts_event, ts_init, created_at, updated_at
            ) VALUES (
                $1, $2, $3, $4, $5, $6, $7, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
            )
            ON CONFLICT (id)
            DO UPDATE
            SET
                instrument_id = $1, bid_price = $2, ask_price = $3, bid_size = $4, ask_size = $5,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Apply migrations so the `trade` table exists
  2. Verify connectivity and pool config (DSN, timeout, pool size)
  3. Read the inner sqlx error for the precise cause and fix it
  4. Retry transient errors with backoff; consider indexing instrument_id/ts_event for large datasets
Defensive patterns

Strategy: retry

Validate before calling

sqlx::query("SELECT 1 FROM trade LIMIT 1").fetch_optional(pool).await?;

Try / catch

let trades = match load_trades(&pool, &instrument_id).await {
    Ok(t) => t,
    Err(e) => { tracing::error!("load_trades: {e:#}"); return Err(e); }
};

Prevention

When it happens

Trigger: Calling `load_trades(pool, instrument_id)` with the DB unreachable, `trade` table missing, query timeout, or pool exhausted.

Common situations: New environment without migrations; network or auth failures; statement timeouts on large trade tables; connection pool contention.

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/efc6dbb518372419. Report an issue: GitHub.