nautechsystems/nautilus_trader · error

Failed to load account ids

Error message

Failed to load account ids: {e}

What it means

This error wraps sqlx failures while querying the list of distinct account ids in `load_accounts`. The SELECT that returns account ids failed, so no accounts can be loaded. The underlying sqlx error is embedded in the message.

Solutions

  1. Confirm DB connectivity and correct DSN in the pool configuration
  2. Run schema migrations so the account-event table exists
  3. Inspect the wrapped sqlx error in `{e}` (undefined table, connection refused, timeout) and address it
  4. Add retry with backoff for transient connection errors
Defensive patterns

Strategy: retry

Validate before calling

sqlx::query("SELECT 1 FROM account_event LIMIT 1").fetch_optional(pool).await.map_err(|e| anyhow::anyhow!("schema check: {e}"))?;

Try / catch

let ids = load_account_ids(pool).await?; // add backoff retry around this for transient errors
for attempt in 0..3 {
    match load_accounts(pool).await { Ok(a) => break a, Err(e) if attempt == 2 => return Err(e), Err(_) => tokio::time::sleep(backoff).await }
}

Prevention

When it happens

Trigger: Calling `load_accounts(pool)` when the database is unreachable, the backing table is missing (migrations not applied), the query times out, or the pool has no usable connections.

Common situations: Fresh environment where migrations were never run; wrong DSN/env config; Postgres restart mid-request; timeouts with many accounts.

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

Appendix: source

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

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

    /// Inserts a `TradeTick` entry via the provided `pool`.
    ///
    /// # Errors
    ///
    /// Returns an error if the SQL INSERT operation fails.
    pub async fn add_trade(pool: &PgPool, trade: &TradeTick) -> anyhow::Result<()> {
        sqlx::query(r#"
            INSERT INTO "trade" (
                instrument_id, price, quantity, aggressor_side, venue_trade_id,

View on GitHub (pinned to 18893faf8b)