nautechsystems/nautilus_trader · error

Failed to check if account event exists: {e}

Error message

Failed to check if account event exists: {e}

What it means

Wraps sqlx failures from the query that checks whether any account event row exists for a given `account_id`. Like the other existence checks, it only errors when the SQL execution fails, not when no events exist (that yields `Ok(false)`). The driver error is wrapped in anyhow context for diagnostics.

Source

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

    /// Checks if any account event exists for the given `account_id` via the provided `pool`.
    ///
    /// # Errors
    ///
    /// Returns an error if the SQL SELECT operation fails.
    pub async fn check_if_account_event_exists(
        pool: &PgPool,
        account_id: AccountId,
    ) -> anyhow::Result<bool> {
        sqlx::query(
            r#"
            SELECT EXISTS(SELECT 1 FROM "account_event" WHERE account_id = $1)
        "#,
        )
        .bind(account_id.to_string())
        .fetch_one(pool)
        .await
        .map(|row| row.get(0))
        .map_err(|e| anyhow::anyhow!("Failed to check if account event exists: {e}"))
    }

    /// Inserts or updates an order event entry via the provided `pool`.
    ///
    /// # Errors
    ///
    /// Returns an error if the SQL INSERT or UPDATE operation fails, or if
    /// serialization of `exec_algorithm_params` fails.
    #[expect(
        clippy::too_many_lines,
        reason = "order event persistence maps the full database schema in one transaction"
    )]
    pub async fn add_order_event(
        pool: &PgPool,
        order_event: Box<dyn OrderEvent>,
        client_id: Option<ClientId>,
    ) -> anyhow::Result<()> {
        let mut transaction = pool.begin().await?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Confirm connectivity with `SELECT 1` on the same pool.
  2. Verify the account event table and its `account_id` column exist (apply migrations).
  3. Check `account_id.to_string()` matches the stored format.
  4. Inspect `{e}` for the driver-level cause; retry transient failures.

Example fix

// before
let has = check_if_account_event_exists(&pool, account_id).await?;
// after
let has = check_if_account_event_exists(&pool, account_id).await
    .map_err(|e| { tracing::error!("account event check failed: {e:#}"); e })?;
Defensive patterns

Strategy: try-catch

Validate before calling

sqlx::query("SELECT 1").execute(pool).await
    .map_err(|e| anyhow::anyhow!("db unreachable: {e}"))?;

Type guard

fn is_transient_db_error(e: &anyhow::Error) -> bool {
    let s = e.to_string().to_lowercase();
    s.contains("connection") || s.contains("timeout") || s.contains("broken pipe")
}

Try / catch

match check_if_account_event_exists(&pool, account_id).await {
    Ok(has_events) => { /* bool result */ }
    Err(e) if is_transient_db_error(&e) => { /* retry with backoff */ }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `check_if_account_event_exists(pool, account_id)` when the database is unreachable, the account-event table is missing or renamed, or the account_id string does not match the column type.

Common situations: Migrations not applied on a fresh environment; account_id UUID formatting mismatch; connection dropped by the server due to idle timeout; wrong database credentials.

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