nautechsystems/nautilus_trader · error

Instrument {first_instrument_id} for the given data not foun

Error message

Instrument {first_instrument_id} for the given data not found in the cache. Add the instrument through `add_instrument()` prior to adding related data.

What it means

Before running, the backtest engine registers all added data and requires that the instrument each data item refers to already exists in the cache. Data must be preceded by add_instrument() for its instrument id; otherwise register_added_data fails so the data cannot be priced or simulated without its instrument definition.

Source

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

    ) -> 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(),
                    "Instrument {first_instrument_id} for the given data not found in the cache. \
                     Add the instrument through `add_instrument()` prior to adding related data."
                );

                if let DataRef::Bar(bar) = first {
                    anyhow::ensure!(
                        bar.bar_type.aggregation_source() == AggregationSource::External,
                        "bar_type.aggregation_source must be External, was {:?}",
                        bar.bar_type.aggregation_source(),
                    );
                }
            }
        }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Call engine.add_instrument(...) for the instrument referenced by the data before add_data/add_data_batch.
  2. Verify the instrument_id in your data matches exactly (symbol and venue casing/format) the added instrument's id.
  3. If batch-loading, add all instruments first, then add data, then sort and run.
  4. For custom data (DataRef::Custom) or DeFi data, note these are exempt from the check — confirm you didn't accidentally wrap domain data as non-custom.

Example fix

// before
engine.add_data(quote_ticks);
engine.add_instrument(instrument);
// after
engine.add_instrument(instrument);
engine.add_data(quote_ticks);
Defensive patterns

Strategy: validation

Validate before calling

// before adding data, ensure every referenced instrument is in the cache
for id in data_instrument_ids {
    if engine.cache.instrument(&id).is_none() {
        panic!("instrument {id} missing from cache; call add_instrument first");
    }
}

Prevention

When it happens

Trigger: Calling engine.add_data(...) or engine.add_data_batch(...) with quotes/trades/bars/deltas whose first item's instrument_id() is not in the cache — i.e. no matching add_instrument() call was made (or was made after adding data).

Common situations: Forgetting add_instrument when loading data-only backtests; instrument id mismatch between the data (e.g. 'EUR/USD.SIM') and the added instrument ('EUR/USD.IDEALPRO'); instruments added on a different engine instance.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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