nautechsystems/nautilus_trader · error
Order {client_order_id} not found
Error message
Order {client_order_id} not found What it means
This panic occurs in the cache's bulk order fetch loop: for each id in client_order_ids it expects self.orders to contain an entry and panics otherwise via unwrap_or_else. The method is designed for callers that already hold guaranteed-valid order ids, so a missing id is treated as a programmer error.
Source
Thrown at crates/common/src/cache/mod.rs:5904
}
/// Retrieves orders corresponding to the `client_order_ids`, optionally filtering by `side`.
///
/// # Panics
///
/// Panics if any `client_order_id` in the set is not found in the cache.
fn get_orders_for_ids(
&self,
client_order_ids: &AHashSet<ClientOrderId>,
side: Option<OrderSide>,
) -> Vec<OrderRef<'_>> {
let mut orders = Vec::new();
for client_order_id in client_order_ids {
let order_cell = self
.orders
.get(client_order_id)
.unwrap_or_else(|| panic!("Order {client_order_id} not found"));
let order = OrderRef::new(order_cell.borrow());
if side.is_none_or(|side| side == order.order_side()) {
orders.push(order);
}
}
// Sort so callers receive a deterministic Vec across runs; the
// underlying client_order_ids set is AHash-backed.
orders.sort_by_key(|o| o.client_order_id());
orders
}
/// Retrieves positions corresponding to the `position_ids`, optionally filtering by `side`.
///
/// Each [`PositionRef`] in the returned vector borrows its underlying cell; mutating any of
/// those positions while the vector is alive will panic at runtime. Drop the vector before
/// issuing writes.View on GitHub (pinned to 18893faf8b)
Solutions
- Confirm every id in client_order_ids was created in this run and is still in the cache
- Filter the id list against cache presence (e.g. a contains/order lookup returning Option) before the bulk fetch
- Check for cache eviction/cleanup that removed orders referenced later
- Log the offending client_order_id and verify it against the source that produced it
Example fix
// before
let ids: Vec<Ustr> = external_report_ids();
let orders = cache.orders(&ids, None);
// after
let ids: Vec<Ustr> = external_report_ids()
.into_iter()
.filter(|id| cache.order(id).is_some())
.collect();
let orders = cache.orders(&ids, None); Defensive patterns
Strategy: validation
Validate before calling
let known: Vec<&Ustr> = client_order_ids
.iter()
.filter(|id| cache.order(id).is_some())
.collect(); Prevention
- Never feed ids from external artifacts (reports, old runs) directly into bulk cache accessors
- Check cache membership before bulk fetch
- Track cache resets and invalidate stored id lists
When it happens
Trigger: Calling the bulk order accessor with a client_order_id that was never created, that was purged from the cache, or that belongs to a different venue/backtest run.
Common situations: Reusing client order ids from a previous session or persisted log whose orders were evicted; a typo in the id; building an id list from external state (fills, orders.csv) not synchronized with the in-memory cache.
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
- Position {position_id} not found
- Order for {} not found to determine position ID
- Order {client_order_id} not found in cache.
- venue-leg quantity calculation validated cumulative fills
- DataActor must be registered before accessing cache
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/23eeb93ca7faa3f9.
Report an issue: GitHub.