nautechsystems/nautilus_trader · error · InstrumentLookupError
InstrumentLookupError::not_found(instrument_id)
Error message
InstrumentLookupError::not_found(instrument_id)
What it means
subscribe_bars requires the bar subscription's instrument to already exist in the client's local instruments cache. If subscription.bar_type.instrument_id() is not present, it fails with InstrumentLookupError::not_found, meaning the instrument must be loaded/added before bars can be subscribed.
Source
Thrown at crates/adapters/coinbase/src/data/mod.rs:663
was_empty
};
if was_empty {
let ws = self.ws_client.clone();
self.spawn_command(async move {
if let Err(e) = ws.subscribe(CoinbaseWsChannel::Status, &[]).await {
log::error!("Failed to subscribe to status channel: {e:?}");
}
});
}
Ok(())
}
fn subscribe_bars(&mut self, subscription: SubscribeBars) -> anyhow::Result<()> {
let instrument_id = subscription.bar_type.instrument_id();
if !self.instruments.contains_key(&instrument_id) {
anyhow::bail!(InstrumentLookupError::not_found(instrument_id));
}
let bar_type = subscription.bar_type;
let subscribed_id = Self::product_id(instrument_id);
let wire_id = self.resolve_wire_product_id(subscribed_id);
if wire_id != subscribed_id {
self.ws_client
.register_subscription_alias(wire_id, subscribed_id);
}
let key = wire_id.to_string();
// Register on the original client so the bar type persists across clones
self.ws_client.register_bar_type(key.clone(), bar_type);
let mut ws = self.ws_client.clone();
self.spawn_command(async move {
ws.add_bar_type(key, bar_type).await;View on GitHub (pinned to 18893faf8b)
Solutions
- Load the instrument first (include it in the instrument provider config / call add_instrument) before subscribing to bars
- Verify the instrument_id string matches a Coinbase product exactly (e.g. BTC-USD)
- Ensure instruments are loaded during connect before any data subscriptions are issued
- Check resolve_wire_product_id mapping if using mapped wire product IDs
Example fix
// before client.subscribe_bars(bars_cmd)?; // instrument never loaded // after assert!(client.instruments().contains_key(&instrument_id)); client.subscribe_bars(bars_cmd)?;
Defensive patterns
Strategy: validation
Validate before calling
if !client.instruments_cache_contains(&subscription.bar_type.instrument_id()) {
return Err(anyhow!("load instrument before subscribing to bars"));
} Prevention
- Load all instruments you intend to subscribe to during client construction/connect
- Keep instrument_id strings exactly matching Coinbase product IDs (e.g. BTC-USD)
- Subscribe to data only after connect() completes instrument loading
- Validate bar_type.instrument_id() against the loaded instrument set in config parsing
When it happens
Trigger: Subscribing to bars for an instrument_id that was never added via instrument provider loading (e.g. a typo'd symbol like 'BTC-USDT.PERP' when only 'BTC-USD' is loaded, or subscribing before connect loaded instruments).
Common situations: Config symbol mismatch with the loaded instrument provider; subscribing immediately after client construction without waiting for instrument load; requesting bars for a product Coinbase does not list.
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
- no Lighter market_index for instrument {instrument_id}
- `handle_bar` is not implemented for `{}`
- Aggregation not time based
- Aggregation type {} not supported for time bars
- {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/dc7e59262ae4cb1a.
Report an issue: GitHub.