nautechsystems/nautilus_trader · error

Instrument {symbol} not in cache

Error message

Instrument {symbol} not in cache

What it means

OKXHttpClient::instrument_from_cache looks up an instrument by symbol in the client's local instruments cache; when absent it errors with `Instrument {symbol} not in cache`. The adapter requires instruments to be pre-loaded before requests that need conversions or definitions.

Source

Thrown at crates/adapters/okx/src/http/client.rs:2171

                retry_delay_ms,
                retry_delay_max_ms,
                environment,
                proxy_url,
            )?),
            instruments_cache: Arc::new(AtomicMap::new()),
            cache_initialized: AtomicBool::new(false),
        })
    }

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

    fn instrument_from_cache_by_id(
        &self,
        instrument_id: InstrumentId,
    ) -> anyhow::Result<InstrumentAny> {
        self.instruments_cache
            .get_cloned(&instrument_id.symbol.inner())
            .ok_or_else(|| InstrumentLookupError::not_found(instrument_id).into())
    }

    /// Cancel all pending HTTP requests.
    pub fn cancel_all_requests(&self) {
        self.inner.cancel_all_requests();
    }

    /// Get the cancellation token for this client.
    pub fn cancellation_token(&self) -> &CancellationToken {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Load the instrument into the cache first (call the client's instrument loading path for that symbol/instrument_id).
  2. Verify the symbol string matches an OKX instrument exactly (e.g. BTC-USDT, BTC-USDT-SWAP).
  3. Add the instrument_id to the client configuration so it is populated during initialization.
  4. Check that you are using the same cache instance the client was built with.

Example fix

// before
let inst = client.instrument_from_cache(symbol)?; // panics-free but errors if absent
// after
if !client.has_instrument(symbol) {
    client.load_instrument(&instrument_id).await?;
}
let inst = client.instrument_from_cache(symbol)?;
Defensive patterns

Strategy: validation

Validate before calling

let loaded: Vec<InstrumentId> = client.instruments();
if !loaded.contains(&instrument_id) {
    client.load_instrument(&instrument_id).await?;
}

Try / catch

match client.instrument_from_cache(symbol) {
    Ok(inst) => inst,
    Err(e) if e.to_string().contains("not in cache") => {
        client.load_instrument(&instrument_id).await?;
        client.instrument_from_cache(symbol)?
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Any HTTP client operation that calls instrument_from_cache with a symbol that was never added via the instrument loading/unsubscribe cycle — e.g. requesting data for an instrument that was not part of the configured instrument_ids.

Common situations: Requesting trades/book for a symbol not in the client's configured instruments; typo'd or stale instrument symbols; using a symbol from a different venue; cache cleared or never populated before first request.

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