nautechsystems/nautilus_trader · error
Cannot create command BatchModifyOrders: state is {:?}, {ord
Error message
Cannot create command BatchModifyOrders: state is {:?}, {order:?} What it means
The order is in a terminal state (is_closed) or has a pending cancel, so a batch modify command cannot be created. Modifying such an order would be invalid; the error includes the order's status and full debug representation.
Source
Thrown at crates/trading/src/strategy/mod.rs:542
order.order_type()
);
}
if Some(*trigger_price) != order.trigger_price() {
updating = true;
}
}
if !updating {
anyhow::bail!(
"Cannot create command BatchModifyOrders: quantity, price, and trigger were \
either None or the same as existing values for {}",
order.client_order_id()
);
}
if order.is_closed() || order.is_pending_cancel() {
anyhow::bail!(
"Cannot create command BatchModifyOrders: state is {:?}, {order:?}",
order.status()
);
}
}
let params = params.filter(|params| !params.is_empty());
let mut modifies = Vec::with_capacity(orders.len());
for (order, (_, quantity, price, trigger_price)) in orders.into_iter().zip(updates) {
if !self.mark_order_pending_update(&order)? {
continue;
}
modifies.push(ModifyOrder::new(
trader_id,
client_id,
strategy_id,View on GitHub (pinned to 18893faf8b)
Solutions
- Filter the batch to orders where !order.is_closed() && !order.is_pending_cancel() before calling
- Re-read current order status from the cache immediately before building the batch
- Handle the race with retry: drop the offending order and re-issue the batch for the rest
Example fix
// before
let batch: Vec<&OrderAny> = tracked_orders.iter().collect();
strategy.modify_orders(&batch, &updates, None, None).await?;
// after
let batch: Vec<&OrderAny> = tracked_orders.iter()
.filter(|o| !o.is_closed() && !o.is_pending_cancel())
.collect();
if !batch.is_empty() {
strategy.modify_orders(&batch, &updates, None, None).await?;
} Defensive patterns
Strategy: validation
Validate before calling
let batch: Vec<_> = orders.iter()
.filter(|o| !o.is_closed() && !o.is_pending_cancel())
.collect(); Type guard
fn modifiable(o: &OrderAny) -> bool { !o.is_closed() && !o.is_pending_cancel() } Prevention
- Re-read order status immediately before batching
- Subscribe to order events and drop stale handles on fill/cancel
- Avoid racing cancel_all with modify_orders on the same orders
When it happens
Trigger: Including a filled, canceled, expired, denied, or pending-cancel order in the batch passed to modify_orders.
Common situations: Stale order handles captured earlier in the strategy while the order filled or was canceled in the meantime; racing between cancel_all and modify_orders; rebatching open orders read from a cache just before they fill.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Cannot batch modify empty order list
- Cannot batch modify orders for different instruments: {} vs
- Cannot include emulated or local orders in batch modify
- Cannot create command BatchModifyOrders: quantity, price, an
- Cannot batch cancel empty order list
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/f3996a32a0be6749.
Report an issue: GitHub.