nautechsystems/nautilus_trader · error

Failed to load bars: {e}

Error message

Failed to load bars: {e}

What it means

load_bars wraps any sqlx error from the SELECT of bars for an instrument_id into anyhow, discarding the typed sqlx error. It indicates the query `SELECT * FROM "bar" WHERE instrument_id = $1 ORDER BY ts_event ASC` failed at execution or row-decoding time. Rows are decoded into the Bar model via row.0, so a schema/type mismatch will surface here.

Source

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

    }

    /// Loads all `Bar` entries for `instrument_id` via the provided `pool`.
    ///
    /// # Errors
    ///
    /// Returns an error if the SQL SELECT or deserialization fails.
    pub async fn load_bars(
        pool: &PgPool,
        instrument_id: &InstrumentId,
    ) -> anyhow::Result<Vec<Bar>> {
        sqlx::query_as::<_, BarRow>(
            r#"SELECT * FROM "bar" 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 bars: {e}"))
    }

    /// Loads all distinct client order IDs from order events via the provided `pool`.
    ///
    /// # Errors
    ///
    /// Returns an error if the SQL SELECT or iteration fails.
    pub async fn load_distinct_order_event_client_ids(
        pool: &PgPool,
    ) -> anyhow::Result<AHashMap<ClientOrderId, ClientId>> {
        let mut map: AHashMap<ClientOrderId, ClientId> = AHashMap::new();
        let result = sqlx::query_as::<_, OrderEventOrderClientIdCombination>(
            r#"
            SELECT DISTINCT ON (client_order_id)
                client_order_id AS "client_order_id",
                client_id AS "client_id"
            FROM "order_event"
            WHERE client_id IS NOT NULL

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the chained sqlx error (`{:?}`) to distinguish connection failure from decode failure.
  2. Run the crate's schema creation/migrations so the `bar` table matches the current model.
  3. If decode errors occur, re-derive or migrate old rows to the current schema (column names/types/count).
  4. Verify the instrument_id string format matches what was stored at insert time.

Example fix

// before
let bars = queries::postgres::load_bars(&pool, instrument_id).await?;
// after
sqlx::query("SELECT 1 FROM \"bar\" LIMIT 1").fetch_optional(&pool).await
    .map_err(|e| anyhow::anyhow!("bar table unreadable, run migrations: {e}"))?;
let bars = queries::postgres::load_bars(&pool, instrument_id).await?;
Defensive patterns

Strategy: try-catch

Validate before calling

let ok = sqlx::query(r#"SELECT 1 FROM \"bar\" LIMIT 1"#).fetch_optional(pool).await.is_ok();
anyhow::ensure!(ok, "bar table missing or unreadable; run migrations first");

Try / catch

match queries::postgres::load_bars(&pool, instrument_id) {
    Ok(bars) if bars.is_empty() => tracing::warn!("no bars for {instrument_id}"),
    Ok(bars) => use_bars(bars),
    Err(e) => fallback_to_alternate_source(e),
}

Prevention

When it happens

Trigger: Calling load_bars when the `bar` table doesn't exist, when stored rows have columns incompatible with the Bar row type (e.g. wrong column count/types after schema change), or when the pool connection fails.

Common situations: Database created by an older nautilus version whose `bar` table lacks columns expected by the current Bar model; connecting to the wrong database; DB offline mid-session.

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