nautechsystems/nautilus_trader · error · anyhow::Error
Cannot cancel order: {e}
Error message
Cannot cancel order: {e} What it means
Raised in `cancel_order` when the cache cannot return an owned snapshot of the order for the given client_order_id, so a CancelOrder command cannot be built. The strategy snapshots the order (releasing the cache borrow before later re-entrant calls) and fails fast if the lookup errors.
Source
Thrown at crates/trading/src/strategy/mod.rs:627
let (trader_id, strategy_id, ts_init) = {
let core = StrategyNative::strategy_core_mut(self);
(
registered_trader_id(core)?,
registered_strategy_id(core)?,
core.clock_mut().timestamp_ns(),
)
};
let params = params.filter(|params| !params.is_empty());
// TODO: Snapshot the order from the cache. Callers identify it by ID; we own the
// snapshot so later calls (which take `&OrderAny` and may re-enter the cache)
// run without holding a live cache borrow.
let order = StrategyNative::strategy_core_mut(self)
.cache_rc()
.borrow()
.try_order_owned(&client_order_id)
.map_err(|e| anyhow::anyhow!("Cannot cancel order: {e}"))?;
if !self.mark_order_pending_cancel(&order)? {
return Ok(());
}
let command = CancelOrder::new(
trader_id,
client_id,
strategy_id,
order.instrument_id(),
order.client_order_id(),
order.venue_order_id(),
UUID4::new(),
ts_init,
params,
None, // correlation_id
);
View on GitHub (pinned to 18893faf8b)
Solutions
- Check cache.order(&client_order_id) is Some before cancelling.
- Ensure cancel_all_orders / timers only run for orders still open in the cache.
- Confirm the strategy owns the orders (correct client_id on submission).
- Handle the error gracefully on reconnection where order state may not yet be reconciled.
Example fix
// before
strategy.cancel_order(&stale_id)?;
// after
if let Some(order) = cache.order(&stale_id) {
if order.is_open() { strategy.cancel_order(&stale_id)?; }
} Defensive patterns
Strategy: validation
Validate before calling
if cache.order(&client_order_id).is_none() { log::warn!("cannot cancel unknown order {client_order_id}"); return; } Try / catch
if let Err(e) = strategy.cancel_order(&id) {
log::warn!("cancel failed for {id}: {e}"); // skip instead of aborting cancel_all
} Prevention
- Verify order is open in cache before cancel
- Guard timer-based expiry handlers against stale IDs
- Reconcile order state after reconnect before cancelling
When it happens
Trigger: Calling `cancel_order` (directly or via cancel_all_orders, dispatch_manager_actions, set_gtd_expiry, expire_gtd_order, reactivate_gtd_timers) with a client_order_id absent from the cache or not retrievable via `try_order_owned`.
Common situations: Cancelling an order already filled/expired and dropped from the live index, cancelling externally submitted orders not tracked by this strategy, or timer-based expiry firing for a stale order.
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
- cached client order {} is associated with venue order {cache
- cached client order {} has no association with requested ven
- DataActor {} must be registered before calling `cache()` - t
- Order {client_order_id} not found
- Position {position_id} not found
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/1b6a54da51035a55.
Report an issue: GitHub.