nautechsystems/nautilus_trader · error

At least one run config is required

Error message

At least one run config is required

What it means

BacktestNode::new was called with an empty configs slice; at least one BacktestRunConfig is required to construct an engine, so node creation fails validation immediately.

Source

Thrown at crates/backtest/src/node.rs:70

)]
pub struct BacktestNode {
    configs: Vec<BacktestRunConfig>,
    engines: AHashMap<String, BacktestEngine>,
}

impl BacktestNode {
    /// Creates a new [`BacktestNode`] instance.
    ///
    /// Validates that configs are non-empty and internally consistent:
    /// - All data config instrument venues must have a matching venue config.
    /// - L2/L3 book types require order book data in the data configs.
    /// - Data config time ranges must be valid (start <= end).
    ///
    /// # Errors
    ///
    /// Returns an error if `configs` is empty or validation fails.
    pub fn new(configs: Vec<BacktestRunConfig>) -> anyhow::Result<Self> {
        anyhow::ensure!(!configs.is_empty(), "At least one run config is required");
        validate_configs(&configs)?;
        Ok(Self {
            configs,
            engines: AHashMap::new(),
        })
    }

    /// Returns the run configurations.
    #[must_use]
    pub fn configs(&self) -> &[BacktestRunConfig] {
        &self.configs
    }

    /// Builds backtest engines from the run configurations.
    ///
    /// For each config, creates a [`BacktestEngine`], adds venues, and loads
    /// instruments from the catalog. If building a config fails with
    /// [`BacktestRunConfig::raise_exception`] disabled, logs the error and skips that config;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass at least one valid BacktestRunConfig to BacktestNode::new
  2. Check the code that builds the configs list for over-aggressive filtering or failed loading
  3. Add an early guard in your app to surface the empty-config condition with your own context

Example fix

// before
let node = BacktestNode::new(configs)?;
// after
anyhow::ensure!(!configs.is_empty(), "no backtest configs loaded");
let node = BacktestNode::new(configs)?;
Defensive patterns

Strategy: validation

Validate before calling

if configs.is_empty() { panic!("at least one BacktestRunConfig is required"); }

Try / catch

match BacktestNode::new(configs) {
    Ok(node) => node,
    Err(e) if e.to_string().contains("At least one run config") => {
        eprintln!("config loader produced no runs: {e}"); std::process::exit(1);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `BacktestNode::new(vec![])` or passing a programmatically built, filtered, or defaulted list that ended up empty.

Common situations: Building configs dynamically from files/CLI/env where a filter or failed parse removed all entries; refactors that changed Vec construction semantics.

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/6270a8a11b4efc49. Report an issue: GitHub.