nautechsystems/nautilus_trader · error

data was empty

Error message

data was empty

What it means

register_added_data requires at least one data item to derive the client id and (when validate=true) the type to validate against. An empty iterator provides no first element, so the engine bails rather than silently registering nothing.

Source

Thrown at crates/backtest/src/engine.rs:464

            validate,
        )?;
        self.data_iterator.add_data_batch(&stream_name, data, true);
        self.sorted = sort;

        Ok(())
    }

    fn register_added_data<'a>(
        &mut self,
        items: impl Iterator<Item = DataRef<'a>> + Clone,
        client_id: Option<ClientId>,
        validate: bool,
    ) -> anyhow::Result<String> {
        #[cfg(not(feature = "defi"))]
        let _ = client_id;

        let Some(first) = items.clone().next() else {
            anyhow::bail!("data was empty");
        };

        if validate {
            // Validate against the first element only and assume the batch is
            // homogeneous (documented contract on add_data).
            #[cfg(feature = "defi")]
            let first_is_defi = matches!(first, DataRef::Defi(_));
            #[cfg(not(feature = "defi"))]
            let first_is_defi = false;

            if !first_is_defi && !matches!(first, DataRef::Custom(_)) {
                let first_instrument_id = first.instrument_id();
                anyhow::ensure!(
                    self.kernel
                        .cache
                        .borrow()
                        .instrument(&first_instrument_id)
                        .is_some(),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the data collection is non-empty before calling add_data/add_data_batch
  2. Log or assert on the data-loading step to catch loaders that return zero rows
  3. Guard the call site: skip registration or surface a clearer error when the list is empty

Example fix

// before
engine.add_data_batch(data)?;
// after
anyhow::ensure!(!data.is_empty(), "no data loaded to add");
engine.add_data_batch(data)?;
Defensive patterns

Strategy: validation

Validate before calling

anyhow::ensure!(!data.is_empty(), "add_data called with empty data");
engine.add_data_batch(data)?;

Try / catch

match engine.add_data(data) {
    Err(e) if e.to_string() == "data was empty" => {
        eprintln!("data loader returned nothing; check source files/filters");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling add_data(vec![]) or add_data_batch with an empty collection, or a filtered/empty iterator passed as `items`.

Common situations: Building data lists conditionally (e.g. loading bars from a directory with no matching files); filter returning empty; API response parsed into zero items.

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