nautechsystems/nautilus_trader · error

Account event does not exist for account: {}

Error message

Account event does not exist for account: {}

What it means

Thrown by `add_account` when it attempted to UPDATE an existing account event (`updated == true`) but `check_if_account_event_exists` reports that no event row exists for the account. The code is trying to update a record that is not present in the database, so it refuses to proceed.

Source

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

        })
    }

    /// Inserts or updates an `AccountState` event via the provided `pool`.
    ///
    /// # Errors
    ///
    /// Returns an error if the SQL INSERT or UPDATE operation fails.
    pub async fn add_account(
        pool: &PgPool,
        updated: bool,
        account_event: AccountState,
    ) -> anyhow::Result<()> {
        if updated {
            let exists =
                Self::check_if_account_event_exists(pool, account_event.account_id).await?;

            if !exists {
                anyhow::bail!(
                    "Account event does not exist for account: {}",
                    account_event.account_id
                );
            }
        }

        let mut transaction = pool.begin().await?;
        let event = serde_json::to_value(&account_event)
            .map_err(|e| anyhow::anyhow!("Failed to serialize account event: {e}"))?;
        let balances = event
            .get("balances")
            .cloned()
            .ok_or_else(|| anyhow::anyhow!("Serialized account event has no balances"))?;
        let margins = event
            .get("margins")
            .cloned()
            .ok_or_else(|| anyhow::anyhow!("Serialized account event has no margins"))?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the account event row exists in the database for that account_id (SELECT from the account events table).
  2. If the record should be new, clear/rebuild the local cache so `updated` is false and the event is INSERTed instead of UPDATEd.
  3. Confirm the process is connected to the intended database/schema; re-add the account so the initial event is persisted first.

Example fix

// before: updating assuming the event exists
queries.add_account(&pool, updated_event).await?;

// after: ensure the account is initialized first, or insert when absent
if !account_event_exists(&pool, &account_id).await? {
    queries.add_account(&pool, initial_event).await?; // INSERT
}
queries.add_account(&pool, updated_event).await?;
Defensive patterns

Strategy: validation

Validate before calling

let exists = sqlx::query_scalar::<_, bool>(
    "SELECT EXISTS(SELECT 1 FROM account_events WHERE account_id = $1)",
)
.bind(account_event.account_id.to_string())
.fetch_one(&pool)
.await?;
if !exists {
    // insert the initial event before any update
}

Try / catch

if let Err(e) = AccountQueries::add_account(&pool, &event).await {
    if e.to_string().contains("does not exist for account") {
        // re-persist the account's initial state, then retry
    } else { return Err(e); }
}

Prevention

When it happens

Trigger: Calling `AccountQueries::add_account(pool, account_event)` with an event whose account_id is not yet persisted while the code path determines the event should update an existing row (e.g. a stale in-memory cache believes the event exists, but the DB row was deleted or belongs to a different database).

Common situations: Pointing the node at a fresh/empty database while reusing an old cache snapshot; someone manually deleted rows from the account events table; using separate databases for write and read pools.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/f6fa91ac9321c691. Report an issue: GitHub.