nautechsystems/nautilus_trader · error
Instrument not found in cache
Error message
Instrument {instrument_id} not found in cache What it means
Raised in `submit_order_internal` (via `submit_order`) when the AX HTTP client cannot return the instrument definition for the order's symbol. The adapter calls `http_client.get_instrument(&symbol)` while preparing an aggressive (marketable) limit order preview, and `ok_or_else` converts the missing instrument into this error. The adapter cannot compute contract quantities or price precision without the instrument definition.
Solutions
- Verify the instrument ID's symbol exists on the Architect AX venue and matches AX's symbol conventions.
- Confirm the instrument is registered/loadable in the cache before submitting orders (subscribe to the instrument or load it at startup).
- Check that the HTTP client points to the intended AX environment (prod vs test) where the instrument is listed.
- Ensure the symbol string passed to `get_instrument` is exact (no whitespace, correct casing).
- If the instrument was recently listed/delisted, refresh the instrument metadata.
Example fix
// before
let qty = Quantity::from(1);
engine.submit_order(order); // instrument never loaded for this venue
// after
if client.get_instrument(&symbol).is_none() {
return Err(anyhow::anyhow!("load or register instrument {symbol} first"));
}
engine.submit_order(order); Defensive patterns
Strategy: validation
Validate before calling
let symbol = instrument_id.symbol.inner();
if http_client.get_instrument(&symbol).is_none() {
anyhow::bail!("instrument {instrument_id} unavailable on AX; register or refresh before trading");
} Try / catch
match engine.submit_order(order) {
Err(e) if e.to_string().contains("not found in cache") => {
log::error!("load AX instrument metadata for {} before submitting", order.instrument_id());
}
other => other?,
} Prevention
- Load/subscribe instrument definitions for every symbol you intend to trade before the session starts.
- Keep venue and symbol conventions consistent; never mix venue instrument IDs.
- Refresh instrument metadata when symbols are newly listed or delisted.
- Point the HTTP client at the same environment as the trading instruments.
When it happens
Trigger: Submitting a MARKET (aggressive limit) order for an instrument whose symbol is not resolvable by `get_instrument` on the AX HTTP API: unknown/misspelled symbol, instrument not listed on AX, or the HTTP lookup fails/returns nothing.
Common situations: Order placed on an instrument ID that belongs to a different venue; symbol format mismatch between internal instrument ID and AX's expected symbol; instrument delisted or not yet loaded into the cache; HTTP client misconfigured pointing at wrong environment.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Cannot modify order
- cannot rebuild Wallet reservations: instrument
- Cannot update position
- Cannot update position
- External order claim for
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/4c5f2cf3cd94267f.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/architect_ax/src/execution.rs:255
let trader_id = self.core.trader_id;
let emitter = self.emitter.clone();
let clock = self.clock;
let http_client = self.http_client.clone();
self.spawn_task("submit_order", async move {
// AX emulates market orders with preview-priced IOC limits, so book moves
// between preview and submission can produce partial fills.
let (price, submit_time_in_force, submit_post_only) = if order_type
== OrderType::Market
{
let preview_result: anyhow::Result<Price> = async {
let symbol = instrument_id.symbol.inner();
let ax_side = AxOrderSide::from(order_side);
let qty_contracts = quantity_to_contracts(quantity)?;
let instrument = http_client.get_instrument(&symbol).ok_or_else(|| {
anyhow::anyhow!("Instrument {instrument_id} not found in cache")
})?;
let request =
PreviewAggressiveLimitOrderRequest::new(symbol, qty_contracts, ax_side);
let response = http_client
.inner
.preview_aggressive_limit_order(&request)
.await
.map_err(|e| {
anyhow::anyhow!("Failed to preview aggressive limit order: {e}")
})?;
if response.remaining_quantity > 0 {
log::warn!(
"Market order book depth insufficient: \
filled_qty={} remaining_qty={} for {instrument_id}",
response.filled_quantity,
response.remaining_quantity,View on GitHub (pinned to 18893faf8b)