nautechsystems/nautilus_trader · error

Starting balances must be provided

Error message

Starting balances must be provided

What it means

Constructor guard in SimulatedExchange::new: the venue configuration supplied an empty starting_balances list. A simulated venue cannot initialize accounts without at least one balance, so construction fails.

Source

Thrown at crates/backtest/src/exchange.rs:219

            .finish_non_exhaustive()
    }
}

impl SimulatedExchange {
    /// Creates a new [`SimulatedExchange`] instance from a venue configuration.
    ///
    /// # Errors
    ///
    /// Returns an error if:
    /// - `starting_balances` is empty.
    /// - `base_currency` is `Some` but `starting_balances` contains multiple currencies.
    pub fn new(
        config: SimulatedVenueConfig,
        cache: Rc<RefCell<Cache>>,
        clock: Rc<RefCell<dyn Clock>>,
    ) -> anyhow::Result<Self> {
        if config.starting_balances.is_empty() {
            anyhow::bail!("Starting balances must be provided")
        }

        if config.base_currency.is_some() && config.starting_balances.len() > 1 {
            anyhow::bail!("single-currency account has multiple starting currencies")
        }

        let default_leverage = config.default_leverage.unwrap_or_else(|| {
            if config.account_type == AccountType::Margin {
                Decimal::from(10)
            } else {
                Decimal::from(1)
            }
        });

        Ok(Self {
            id: config.venue,
            oms_type: config.oms_type,
            account_type: config.account_type,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Provide at least one Money balance in SimulatedVenueConfig.starting_balances matching the account base currency
  2. For multi-currency (margin) accounts, include all needed currency balances
  3. Validate the config before constructing the exchange

Example fix

// before
let config = SimulatedVenueConfig { starting_balances: vec![], .. };
// after
let config = SimulatedVenueConfig {
    starting_balances: vec![Money::from("1_000_000 USD")],
    ..
};
Defensive patterns

Strategy: validation

Validate before calling

anyhow::ensure!(
    !config.starting_balances.is_empty(),
    "SimulatedVenueConfig.starting_balances must contain at least one balance"
);
let exchange = SimulatedExchange::new(config, cache, clock)?;

Try / catch

match SimulatedExchange::new(config, cache, clock) {
    Err(e) if e.to_string().contains("Starting balances must be provided") => {
        eprintln!("set starting_balances in the venue config");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Constructing an exchange via SimulatedVenueConfig whose starting_balances vec is empty; building config programmatically without pushing balances.

Common situations: Forgot to set starting_balances in venue config; parsing config where balances section was omitted; dynamically generated balances filtered to empty.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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