nautechsystems/nautilus_trader · error

OrderList denied: no orders to submit

Error message

OrderList denied: no orders to submit

What it means

submit_order_list refuses to process an empty order list. An OrderList must contain at least one INITIALIZED order, so an empty collection is rejected up front with an error log and bail instead of creating an empty list in the cache.

Source

Thrown at crates/trading/src/strategy/mod.rs:206

    /// Submits an order list.
    ///
    /// # Errors
    ///
    /// Returns an error if the strategy is not registered, the order list is invalid,
    /// or order list submission fails.
    fn submit_order_list(
        &mut self,
        mut orders: Vec<OrderAny>,
        position_id: Option<PositionId>,
        client_id: Option<ClientId>,
        params: Option<Params>,
    ) -> anyhow::Result<()>
    where
        Self: StrategyNative,
    {
        if orders.is_empty() {
            log::error!("OrderList denied: no orders to submit");
            anyhow::bail!("OrderList denied: no orders to submit");
        }

        for order in &orders {
            if order.status() != OrderStatus::Initialized {
                anyhow::bail!(
                    "Order in list denied: invalid status for {}, expected INITIALIZED",
                    order.client_order_id()
                );
            }
        }

        let first_venue = orders[0].instrument_id().venue;
        for order in &orders {
            if order.instrument_id().venue != first_venue {
                anyhow::bail!(
                    "OrderList denied: orders must share the same venue; \
                     expected {first_venue}, found {} on {}",
                    order.instrument_id().venue,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the list length before calling and skip submission when empty.
  2. Ensure at least one order is created via the order factory before building the list.
  3. Log or handle the empty-batch case explicitly in the calling code.

Example fix

// before
self.submit_order_list(OrderList(orders))

// after
if orders:
    self.submit_order_list(OrderList(orders))
Defensive patterns

Strategy: validation

Validate before calling

if not orders:
    return  # nothing to submit; skip instead of raising

Type guard

def is_nonempty_order_list(orders) -> bool:
    return isinstance(orders, (list, tuple)) and len(orders) > 0

Try / catch

try:
    self.submit_order_list(order_list)
except RuntimeError as e:
    if "no orders to submit" in str(e):
        self.log.warning("skipped empty order list")
    else:
        raise

Prevention

When it happens

Trigger: Calling strategy.submit_order_list with an empty orders sequence — typically when orders were built conditionally and no condition matched.

Common situations: Filter logic producing zero orders at runtime; a upstream signal/batch that returned no entries; refactor that moved order creation after the submit call.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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