nautechsystems/nautilus_trader · error

OrderList denied: {e}

Error message

OrderList denied: {e}

What it means

After construction, the OrderList is validated via order_list.validate(); if the list is internally inconsistent (e.g. invalid quantities/prices, or missing parameters for composite list types like bracket/OCO), submit_order_list logs and bails with the embedded validation message.

Source

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

            return Ok(());
        }

        let core = StrategyNative::strategy_core_mut(self);

        let trader_id = registered_trader_id(core)?;
        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!(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the embedded validation message ({e}) — it names the exact violated constraint.
  2. Build lists via the order factory's list creators (bracket, OTO, OCO) with complete, valid parameters.
  3. Validate quantities/prices are set and positive before calling submit_order_list.

Example fix

// before
bracket = self.order_factory.bracket(limit_order)  # missing stop params

// after
bracket = self.order_factory.bracket(
    limit_order,
    stop_side=OrderSide.SELL,
    stop_trigger_price=stop_px,
    stop_quantity=qty,
)
Defensive patterns

Strategy: validation

Validate before calling

for o in orders:
    if o.quantity <= 0 or (hasattr(o, 'price') and o.price is not None and o.price <= 0):
        raise ValueError(f"invalid order parameters: {o.client_order_id}")

Type guard

def list_params_complete(orders) -> bool:
    return bool(orders) and all(getattr(o, 'quantity', None) for o in orders)

Try / catch

try:
    self.submit_order_list(order_list)
except RuntimeError as e:
    if e.args and "OrderList denied" in str(e.args[0]):
        self.log.error(f"order list failed validation: {e}")
    else:
        raise

Prevention

When it happens

Trigger: Submitting a list whose validate() fails — commonly a bracket list created with missing/invalid stop or limit parameters, or hand-constructed lists with inconsistent fields.

Common situations: Malformed bracket/OTO/OCO construction parameters passed to the order factory; custom order building that bypasses factory invariants; quantity/price fields left unset or negative.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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