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

  1. Filter the batch to orders where !order.is_closed() && !order.is_pending_cancel() before calling
  2. Re-read current order status from the cache immediately before building the batch
  3. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/f3996a32a0be6749. Report an issue: GitHub.