nautechsystems/nautilus_trader · error · anyhow::Error
No instrument cached for clob_pair_id {clob_pair_id}
Error message
No instrument cached for clob_pair_id {clob_pair_id} What it means
parse_ws_order_report maps a dYdX WebSocket order update to an OrderStatusReport, which requires the corresponding instrument. The instrument cache is looked up by clob_pair_id; if no instrument was cached for that ID the update cannot be converted and this error is thrown (after logging the missing ID). This typically means instrument loading or the websocket subscriptions are out of sync.
Source
Thrown at crates/adapters/dydx/src/websocket/parse.rs:94
/// - HTTP parser fails.
pub fn parse_ws_order_report(
ws_order: &DydxWsOrderSubaccountMessageContents,
instrument_cache: &InstrumentCache,
order_contexts: &DashMap<u32, OrderContext>,
encoder: &ClientOrderIdEncoder,
account_id: AccountId,
ts_init: UnixNanos,
) -> anyhow::Result<OrderStatusReport> {
let clob_pair_id: u32 = ws_order.clob_pair_id.parse().context(format!(
"Failed to parse clob_pair_id '{}'",
ws_order.clob_pair_id
))?;
let instrument = instrument_cache
.get_by_clob_id(clob_pair_id)
.ok_or_else(|| {
instrument_cache.log_missing_clob_pair_id(clob_pair_id);
anyhow::anyhow!("No instrument cached for clob_pair_id {clob_pair_id}")
})?;
let http_order = convert_ws_order_to_http(ws_order)?;
let mut report = parse_order_status_report(&http_order, &instrument, account_id, ts_init)?;
let dydx_client_id = ws_order.client_id.parse::<u32>().ok();
let dydx_client_metadata = ws_order
.client_metadata
.as_ref()
.and_then(|s| s.parse::<u32>().ok())
.unwrap_or(crate::grpc::DEFAULT_RUST_CLIENT_METADATA);
log::debug!(
"[WS_ORDER_RECV] dYdX client_id='{}' meta={:#x} (parsed u32={:?}) | status={:?} | clob_pair={} | side={:?} | size={} | filled={}",
ws_order.client_id,
dydx_client_metadata,
dydx_client_id,
ws_order.status,View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the HTTP instrument load/populate of the instrument cache completes before spawning the WS stream handler
- Subscribe only to markets whose instruments are cached, or load the missing instrument for that clob_pair_id
- Check the logged 'missing clob_pair_id' to identify which market needs to be added to the cache
- Restart/reconnect after refreshing instruments so the cache is current
Example fix
// before spawn_ws_stream_handler(stream) // instruments not yet loaded // after load_all_instruments(&mut instrument_cache).await?; spawn_ws_stream_handler(stream);
Defensive patterns
Strategy: validation
Validate before calling
if instrument_cache.get_by_clob_id(clob_pair_id).is_none() {
return Err(anyhow!("instrument for clob_pair_id {clob_pair_id} not loaded; load instruments before streaming"));
}
// proceed to parse_ws_order_report Type guard
fn is_clob_cached(cache: &InstrumentCache, id: u64) -> bool {
cache.get_by_clob_id(id).is_some()
} Try / catch
match parse_ws_order_report(...) {
Err(e) if e.to_string().contains("No instrument cached for clob_pair_id") => {
warn!("skipping order update for uncached market");
}
Err(e) => return Err(e),
Ok(r) => publish(r),
} Prevention
- Always finish HTTP instrument loading before starting WS stream handlers
- Subscribe only to markets present in the instrument cache
- Refresh the cache when new markets are listed
When it happens
Trigger: Receiving a WebSocket order status update whose clob_pair_id is not present in the instrument cache — e.g. an order on a market never loaded via the HTTP instruments endpoint, or the cache was cleared/not populated before the WS stream started.
Common situations: Starting the websocket stream before instruments finish loading; trading a newly listed market while cached instruments are stale; subscribing to channels for markets outside the configured instruments.
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 instrument cached for market '{}'. Available: {:?}
- Missing required field: client_metadata
- Missing required field: order_id
- slots lock poisoned
- subscription state lock poisoned
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/9035def17474fda2.
Report an issue: GitHub.