nautechsystems/nautilus_trader · error

Failed to load order ids: {e}

Error message

Failed to load order ids: {e}

What it means

load_orders first queries the distinct client_order_ids from the order events table; if that SELECT fails the sqlx error is wrapped in this message. No orders are loaded when this fires since the id list could not be built.

Source

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

    ///
    /// # Errors
    ///
    /// Returns an error if loading events or SQL operations fail.
    pub async fn load_orders(pool: &PgPool) -> anyhow::Result<Vec<OrderAny>> {
        let mut orders: Vec<OrderAny> = Vec::new();
        let client_order_ids: Vec<ClientOrderId> = sqlx::query(
            r#"
            SELECT DISTINCT client_order_id FROM "order_event"
        "#,
        )
        .fetch_all(pool)
        .await
        .map(|rows| {
            rows.into_iter()
                .map(|row| ClientOrderId::from(row.get::<&str, _>(0)))
                .collect()
        })
        .map_err(|e| anyhow::anyhow!("Failed to load order ids: {e}"))?;
        for id in client_order_ids {
            let order = Self::load_order(pool, &id).await?;
            if let Some(order) = order {
                orders.push(order);
            }
        }
        Ok(orders)
    }

    /// Replaces the fill event log for a `position_id` via the provided `pool`.
    ///
    /// # Errors
    ///
    /// Returns an error if the fill is invalid or if the SQL operations fail.
    pub async fn add_position(
        pool: &PgPool,
        position_id: PositionId,
        event: &OrderFilled,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the wrapped sqlx error for the root cause (missing relation, connection refused, etc.).
  2. Apply the nautilus SQL migrations to create the order tables.
  3. Verify DB credentials and that the user can SELECT from the order event table.
  4. Check pool connectivity settings (max lifetime, timeouts) if failures are intermittent.

Example fix

// before
let orders = DatabaseQuery::load_orders(&pool).await?;
// after
let orders = DatabaseQuery::load_orders(&pool).await
    .context("ensure migrations applied and DB reachable")?;
Defensive patterns

Strategy: retry

Validate before calling

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

Try / catch

match load_orders(&pool).await {
    Err(e) if is_transient_db_error(&e) => retry_with_backoff(3),
    other => other,
}

Prevention

When it happens

Trigger: Calling DatabaseQuery::load_orders(pool) and the id-enumeration query fails: missing table, connection failure, or SQL error surfaced through sqlx and wrapped by anyhow.

Common situations: Fresh database without migrations applied; database unreachable at startup; insufficient SELECT privileges on the order tables.

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