nautechsystems/nautilus_trader · error · anyhow::Error

cannot rebuild Wallet reservations for account {account_id}

Error message

cannot rebuild Wallet reservations for account {account_id} and instrument {instrument_id}

What it means

During initialize_wallet_orders, the Portfolio delegates reservation rebuilding to the account's update_orders(), which returns None when it cannot apply the orders. Because None carries no reason, the Portfolio raises this bail identifying the account and instrument. It means the Wallet account state could not be updated with the given orders for that instrument (e.g. insufficient/debit balance data or an invariant failure inside the account update).

Source

Thrown at crates/portfolio/src/portfolio.rs:1797

                    anyhow::anyhow!(
                        "cannot rebuild Wallet reservations: account {account_id} not found"
                    )
                })?;
                let instrument = cache.instrument(&instrument_id).cloned().ok_or_else(|| {
                    anyhow::anyhow!(
                        "cannot rebuild Wallet reservations: instrument {instrument_id} not found"
                    )
                })?;
                (account, instrument)
            };
            let order_refs = orders.iter().collect::<Vec<_>>();
            let Some((updated_account, _)) = self.inner.borrow().accounts.update_orders(
                &account,
                &instrument,
                &order_refs,
                self.clock.borrow().timestamp_ns(),
            ) else {
                anyhow::bail!(
                    "cannot rebuild Wallet reservations for account {account_id} and instrument {instrument_id}"
                );
            };
            self.cache.borrow_mut().update_account(&updated_account)?;
        }

        log::info!(
            color = if total_orders > 0 { LogColor::Blue as u8 } else { LogColor::Normal as u8 };
            "Initialized {} Wallet reservation{}",
            total_orders,
            if total_orders == 1 { "" } else { "s" }
        );
        Ok(())
    }

    /// Initializes account margin based on existing open positions.
    ///
    /// # Panics

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check why update_orders returned None: verify the Wallet account holds the base and quote balances required for each open order's instrument
  2. Re-sync the account with a fresh account state (account_state event) before rebuilding reservations
  3. Remove or cancel stale open orders that reference balances no longer present
  4. Enable balance consistency checks in the venue client so balances are persisted with the account

Example fix

// before: rebuilding without account balance snapshot
let portfolio = Portfolio::new(cache, clock, ...);
portfolio.initialize_wallet_orders()?;
// after: ensure account state (with balances) is in cache first
let account_state = venue_client.account_state(ts_ns)?;
cache.update_account_from_state(account_state);
let portfolio = Portfolio::new(cache, clock, ...);
portfolio.initialize_wallet_orders()?;
Defensive patterns

Strategy: validation

Validate before calling

// Ensure wallet balances exist for every open order's instrument currencies
for order in cache.orders_open() {
    if let Some(inst) = cache.instrument(&order.instrument_id()) {
        let acct = cache.account_for_venue(inst.id.venue).unwrap();
        assert!(acct.balance(&inst.quote_currency).is_some(), "missing quote balance");
    }
}

Try / catch

if let Err(e) = portfolio.initialize_wallet_orders() {
    if e.to_string().starts_with("cannot rebuild Wallet reservations for account") {
        // re-sync account state from venue, then retry once
    }
    return Err(e);
}

Prevention

When it happens

Trigger: initialize_wallet_orders() calls accounts.update_orders(...) for a grouped (account, instrument) set of open orders and the method returns None — typically when the Wallet account lacks the balances needed to compute reservations (e.g. a missing debit balance) for that instrument's currency.

Common situations: Rebuilding state after restart where the account snapshot is missing a balance currency that open orders need; balance events lost or partially persisted; orders persisted for an instrument whose quote/base balances were never reported by the venue.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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