nautechsystems/nautilus_trader · error

Serialized account event has no balances

Error message

Serialized account event has no balances

What it means

After serializing the AccountState to a JSON value, add_account requires a "balances" key to bind into the account_event table. This error means the serialized object contained no "balances" field — the AccountState struct's serde representation lacks that key (skipped via #[serde(skip)] or renamed) or serialized to a non-object shape.

Source

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

        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"))?;

        sqlx::query(
            r#"
            INSERT INTO "account" (id) VALUES ($1) ON CONFLICT (id) DO NOTHING
        "#,
        )
        .bind(account_event.account_id.to_string())
        .execute(&mut *transaction)
        .await
        .map(|_| ())
        .map_err(|e| anyhow::anyhow!("Failed to insert into account table: {e}"))?;

        sqlx::query(r#"
            INSERT INTO "account_event" (

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Print or log serde_json::to_value(&account_event) keys to see what fields actually exist.
  2. Confirm you are constructing a genuine AccountState from this crate version whose Serialize includes "balances"; rebuild the crate if binaries are stale.
  3. Remove any #[serde(skip_serializing_if)] or rename on the balances field, or pass an explicit empty Vec instead of skipping.
  4. If balances are legitimately absent, persist an empty JSON array rather than omitting the field.

Example fix

// before: field skipped when empty
#[serde(skip_serializing_if = "Vec::is_empty")]
pub balances: Vec<AccountBalance>,

// after: always serialize the key
pub balances: Vec<AccountBalance>,
Defensive patterns

Strategy: validation

Validate before calling

// confirm the serialized event carries balances
let json = serde_json::to_value(&account_event)?;
assert!(json.get("balances").is_some(), "AccountState serialization missing 'balances'");

Type guard

fn has_balances(state: &AccountState) -> bool {
    serde_json::to_value(state)
        .ok()
        .and_then(|v| v.get("balances").cloned())
        .is_some()
}

Try / catch

match add_account(&pool, updated, state).await {
    Err(e) if e.to_string().contains("no balances") => {
        log::error!("event type lost its balances field — check serde attrs/versions");
    }
    other => other?,
}

Prevention

When it happens

Trigger: add_account receives an AccountState whose Serialize impl omits the balances field — e.g. a custom/renamed serde attribute, a subclassed or hand-rolled event type, or an empty balances vector serialized as a skipped/None field.

Common situations: Upgrading NautilusTrader while a cached/stale build still expects the old field name; using a custom AccountState-like type with #[serde(skip_serializing_if)] on balances; deserializing then re-serializing events through a lossy intermediate format that dropped the key.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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