nautechsystems/nautilus_trader · error

Wallet balance snapshot has no native currency

Error message

Wallet balance snapshot has no native currency

What it means

account_balances builds a Vec<AccountBalance> from a wallet snapshot, requiring a native currency balance as the first entry. This error means the snapshot's native_currency field is None — the wallet snapshot is incomplete and cannot be converted into account balances. The library throws it because an account balance report without the chain's native asset would be misleading.

Source

Thrown at crates/model/src/defi/wallet.rs:184

    /// # Errors
    ///
    /// Returns an error if the snapshot is incomplete, contains duplicate currencies, or a token
    /// amount cannot be represented as money.
    pub fn as_account_balances(&self) -> anyhow::Result<Vec<AccountBalance>> {
        let mut token_balances = self.token_balances.iter().collect::<Vec<_>>();
        token_balances.sort_unstable_by_key(|balance| balance.token.address);
        self.account_balances(token_balances)
    }

    fn account_balances<'a>(
        &'a self,
        token_balances: impl IntoIterator<Item = &'a TokenBalance>,
    ) -> anyhow::Result<Vec<AccountBalance>> {
        self.validate_token_addresses()?;

        let native_currency = self
            .native_currency
            .ok_or_else(|| anyhow::anyhow!("Wallet balance snapshot has no native currency"))?;
        let mut currencies = HashSet::new();
        currencies.insert(native_currency.currency);

        let mut balances = Vec::with_capacity(self.token_balances.len() + 1);
        balances.push(AccountBalance::new_checked(
            native_currency,
            Money::zero(native_currency.currency),
            native_currency,
        )?);

        for token_balance in token_balances {
            let total = token_balance.as_money()?;
            if !currencies.insert(total.currency) {
                anyhow::bail!(
                    "Wallet balance snapshot contains duplicate currency {}",
                    total.currency
                );
            }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Call set_native_currency_balance() (or replace_balances()) before as_account_balances().
  2. Guard with is_token_universe_initialized-style checks / check native currency presence before converting.
  3. Re-request the full balance snapshot from the adapter instead of converting a partial one.
  4. Wait for the wallet's initial snapshot event before consuming account balances.

Example fix

// before
let balances = snapshot.as_account_balances()?;
// after
if !snapshot.is_token_universe_initialized() { /* or track native presence */ }
let balances = match snapshot.as_account_balances() {
    Ok(b) => b,
    Err(e) if e.to_string().contains("no native currency") => {
        tracing::warn!("wallet snapshot not yet populated");
        return Ok(vec![]);
    }
    Err(e) => return Err(e),
};
Defensive patterns

Strategy: validation

Validate before calling

fn snapshot_has_native(snapshot: &WalletBalanceSnapshot) -> bool {
    snapshot.as_account_balances().is_ok() // or expose/track native_currency presence at construction
}

Try / catch

match snapshot.as_account_balances() {
    Ok(balances) => balances,
    Err(e) if e.to_string().contains("no native currency") => {
        tracing::debug!("wallet snapshot incomplete; skipping balance report");
        Vec::new()
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling as_account_balances() on a WalletBalanceSnapshot created via the empty constructor (or any snapshot) before set_native_currency_balance()/replace_balances() has been called to populate the native balance.

Common situations: Querying balances before the first balance snapshot arrives from the adapter; constructing the snapshot manually and forgetting the native currency; a failed native balance fetch leaving the field unset while token balances were updated.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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