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
- Verify the account event row exists in the database for that account_id (SELECT from the account events table).
- If the record should be new, clear/rebuild the local cache so `updated` is false and the event is INSERTed instead of UPDATEd.
- 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
- Never delete account event rows manually; use the library's flush mechanisms.
- Ensure all nodes share the same database — don't split read/write pools.
- Initialize accounts (persist their first event) before applying updates.
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
- No persisted order events found for {client_order_id}
- Verified action nonce does not match the active intent
- Implement FromRow for FuturesSpread
- Implement FromRow for OptionSpread
- Execution schema version {} is newer than supported version
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/f6fa91ac9321c691.
Report an issue: GitHub.