nautechsystems/nautilus_trader · error · anyhow::Error
Cannot submit order list {order_list.id}: cache is currently
Error message
Cannot submit order list {order_list.id}: cache is currently borrowed What it means
Before adding the order list to the Cache, `submit_order_list` attempts a mutable borrow of the shared Cache via `try_borrow_mut`. If the Cache is already borrowed on the same thread the submission fails with `Cannot submit order list {order_list.id}: cache is currently borrowed`. This is a single-threaded re-entrancy/borrow conflict, not a lock contention issue.
Source
Thrown at crates/trading/src/strategy/mod.rs:265
let strategy_id = registered_strategy_id(core)?;
let ts_init = core.clock_mut().timestamp_ns();
// TODO: Replace with fluent builder API for order list construction
let order_list = if orders.first().is_some_and(|o| o.order_list_id().is_some()) {
OrderList::from_orders(&orders, ts_init)
} else {
core.order_factory().create_list(&mut orders, ts_init)
};
if let Err(e) = order_list.validate() {
log::error!("OrderList denied: {e}");
anyhow::bail!("OrderList denied: {e}");
}
{
let cache_rc = core.cache_rc();
let mut cache = cache_rc.try_borrow_mut().map_err(|_| {
anyhow::anyhow!(
"Cannot submit order list {}: cache is currently borrowed",
order_list.id
)
})?;
if cache.order_list_exists(&order_list.id) {
anyhow::bail!("OrderList denied: duplicate {}", order_list.id);
}
for order in &orders {
if cache.order_exists(&order.client_order_id()) {
anyhow::bail!(
"Order in list denied: duplicate {}",
order.client_order_id()
);
}
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Defer the submission out of the nested context (e.g. queue the order list and submit from `on_start` or a timer/event after dispatch completes).
- Drop any retained cache borrow guards before calling `submit_order_list`.
- Avoid submitting orders while iterating cache collections in the same call stack.
- If triggered by an exec algorithm, restructure so child orders are submitted from a fresh event-cycle callback.
Example fix
// before
for order in self.cache.orders_open(...): # holds cache borrow
self.submit_order_list(build_list(order)) # re-entrant borrow -> error
// after
pending = [build_list(o) for o in list(self.cache.orders_open(...))]
for ol in pending:
self.submit_order_list(ol) # submitted after iteration completes Defensive patterns
Strategy: fallback
Try / catch
try:
self.submit_order_list(order_list)
except Exception as e:
if 'cache is currently borrowed' in str(e):
self._deferred_lists.append(order_list) # submit later from a timer/event
else:
raise Prevention
- Do not submit orders while iterating cache collections
- Drop cache borrow guards before submission calls
- Queue submissions during dispatch and flush from a later callback
- Avoid deeply nested handler stacks that re-enter submission paths
When it happens
Trigger: Calling `submit_order_list` while a mutable cache borrow is outstanding — e.g. from inside a callback while the engine dispatch holds the cache, or while user code holds a cache handle obtained earlier.
Common situations: Submitting orders from within `on_event`/handlers nested inside a cache-borrowing code path; retaining a cache borrow guard across the submit call; custom adapters or exec algorithms re-entering submission during cache iteration.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Cannot set external order claims: {e}
- Unsupported `OrderSide` for Binance: {value:?}
- Invalid order side: {e}
- DataActor {} must be registered before calling `cache()` - t
- Order {client_order_id} not found
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/0f9c0d8bf2d36d60.
Report an issue: GitHub.