nautechsystems/nautilus_trader · error · anyhow::Error

Instrument {symbol} not found in cache, ensure instruments l

Error message

Instrument {symbol} not found in cache, ensure instruments loaded first

What it means

instrument_from_cache looks up a cached InstrumentAny for a BitMEX symbol and errors if it is absent. Order operations need the instrument's price precision, tick size, etc., so the client refuses to act on symbols whose instrument definitions were never loaded into the cache.

Source

Thrown at crates/adapters/bitmex/src/http/client.rs:1485

    /// # Errors
    ///
    /// Returns an error if credentials are missing, the request fails, or the API returns an error.
    pub async fn get_orders(
        &self,
        params: GetOrderParams,
    ) -> Result<Vec<BitmexOrder>, BitmexHttpError> {
        let inner = self.inner.clone();
        inner.get_orders(params).await
    }

    /// Get instrument from the instruments cache (if found).
    ///
    /// # Errors
    ///
    /// Returns an error if the instrument is not found in the cache.
    fn instrument_from_cache(&self, symbol: Ustr) -> anyhow::Result<InstrumentAny> {
        self.get_instrument(&symbol).ok_or_else(|| {
            anyhow::anyhow!(
                "Instrument {symbol} not found in cache, ensure instruments loaded first"
            )
        })
    }

    /// Returns the cached price precision for the given symbol.
    ///
    /// # Errors
    ///
    /// Returns an error if the instrument was never cached (for example, if
    /// instruments were not loaded prior to use).
    pub fn get_price_precision(&self, symbol: Ustr) -> anyhow::Result<u8> {
        self.instrument_from_cache(symbol)
            .map(|instrument| instrument.price_precision())
    }

    /// Get user margin information for a specific currency.
    ///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Load all instruments into the cache at startup before submitting or modifying orders.
  2. Verify the symbol exactly matches a cached instrument symbol (use a symbol from the cache).
  3. Add a pre-flight cache lookup for the symbol and fail fast with a clearer message.
  4. Ensure the data client that populates instruments was initialized before the execution client is used.

Example fix

// before
client.submit_order(order)?; // fails if symbol not cached
// after
if cache.instrument(&order.instrument_id()).is_none() {
    anyhow::bail!("instrument {} not loaded; load instruments first", order.instrument_id());
}
client.submit_order(order)?;
Defensive patterns

Strategy: validation

Validate before calling

// Rust
if cache.instrument(&instrument_id).is_none() {
    anyhow::bail!("instrument {} not loaded into cache", instrument_id);
}

Type guard

// Rust
fn instrument_loaded(cache: &CacheView, id: InstrumentId) -> bool {
    cache.instrument(&id).is_some()
}

Try / catch

// Rust
match client.submit_order(order).await {
    Err(e) if e.to_string().contains("not found in cache") => {
        load_instruments(&mut cache).await?;
        client.submit_order(order).await?
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling get_price_precision, submit_order, cancel_order, cancel_orders, cancel_all_orders, or modify_order with a symbol that was never added to the cache — i.e. instruments were not loaded (e.g. generate_order_status_reports/load_instruments not run) before submitting.

Common situations: Starting a strategy without loading instruments first, submitting orders for a newly listed or delisted BitMEX symbol, a symbol casing/format mismatch between the order and the cached instrument, or a fresh process restart with an empty cache.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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