nautechsystems/nautilus_trader · error · anyhow::Error
Instrument {instrument_id} not found in cache
Error message
Instrument {instrument_id} not found in cache What it means
While pricing an emulated MARKET order, the adapter looks up the instrument in the HTTP client's instrument cache (populated when the data client connects and fetches instrument definitions). get_instrument(symbol) returning None means the symbol portion of the InstrumentId has no cached definition, so lot size and price precision are unknown and the preview request cannot be built. Submission aborts before reaching the venue.
Source
Thrown at crates/adapters/architect_ax/src/execution.rs:232
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::try_from(order_side)
.map_err(|e| anyhow::anyhow!("Invalid order side: {e}"))?;
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 a4b06ed870)
Solutions
- Verify the exact symbol with the AX instruments endpoint or the loaded cache and use that spelling in the InstrumentId (SYMBOL.AX)
- Gate order submission until the data client is connected and the instrument exists (cache.instrument(id).is_some())
- Ensure the AX data client for the same instruments is started before/at execution client start so definitions are fetched
- Reload instruments (reconnect the data client) if the venue listed new symbols after startup
Example fix
// before: submits immediately, cache miss -> error
self.submit_order(&order);
// after: gate on instrument availability
if self.cache.instrument(instrument.id).is_some() {
self.submit_order(&order);
} else {
self.warning(&format!("{} not loaded yet, skipping", instrument.id));
} Defensive patterns
Strategy: validation
Validate before calling
// Gate market orders on a cached instrument definition
if self.cache.instrument(instrument.id).is_none() {
self.warning(&format!(
"instrument {} not loaded; deferring order",
instrument.id
));
return; // retry on a later signal/timer
} Prevention
- Start the AX data client for your instruments before the execution client sends orders
- Log the exact InstrumentId you submit and diff it against the AX instruments list once at startup
- Treat 'instrument not in cache' as a soft condition: skip and retry the signal, do not crash the strategy
When it happens
Trigger: Submitting a market order before the AX data client finished loading instruments; using an InstrumentId whose symbol does not exactly match AX's symbol (case, dash, prefix differences); routing an order for another venue's instrument to the AX execution client; venue added new symbols after your session loaded instruments.
Common situations: Engine start race: trading logic fires on first bar before instruments are loaded; symbol spelled differently on AX than on the data source used for the signal (e.g. 'BTC-PERP' vs 'BTCUSD'); strategies shared across venues routed by a Router that sends the wrong instrument to AX.
Related errors
- Invalid order side: {e}
- Failed to preview aggressive limit order: {e}
- No liquidity available for market order on {instrument_id}
- Authentication failed: {e}
- Timeout waiting for account {account_id} to be registered af
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/4c5f2cf3cd94267f.
Report an issue: GitHub.