nautechsystems/nautilus_trader · error

limit_price is required for batch order type {order_type:?}

Error message

limit_price is required for batch order type {order_type:?}

What it means

Kraken Spot WS batch order submission requires a limit price for any order type classified as limit-like (Limit, StopLimit, LimitIfTouched). build_batch_order bails out before constructing the batch message when such an order has no price attached. The adapter cannot map the order to Kraken's batch-add schema without it.

Source

Thrown at crates/adapters/kraken/src/execution/spot.rs:1027

    }

    let kraken_order_type = match order_type {
        OrderType::Market => KrakenOrderType::Market,
        OrderType::Limit => KrakenOrderType::Limit,
        OrderType::StopMarket => KrakenOrderType::StopLoss,
        OrderType::StopLimit => KrakenOrderType::StopLossLimit,
        OrderType::MarketIfTouched => KrakenOrderType::TakeProfit,
        OrderType::LimitIfTouched => KrakenOrderType::TakeProfitLimit,
        ty => anyhow::bail!("Unsupported order type for Kraken WS batch: {ty:?}"),
    };

    let is_limit_order = matches!(
        order_type,
        OrderType::Limit | OrderType::StopLimit | OrderType::LimitIfTouched
    );

    if is_limit_order && order.price().is_none() {
        anyhow::bail!("limit_price is required for batch order type {order_type:?}");
    }

    let ws_tif =
        compute_ws_time_in_force(is_limit_order, order.time_in_force(), order.expire_time())?;
    let expire_time = match (ws_tif, order.expire_time()) {
        (Some(KrakenTimeInForce::GoodTilDate), Some(ts)) => Some(format_expire_time(ts)),
        _ => None,
    };

    let is_conditional = matches!(
        order_type,
        OrderType::StopMarket
            | OrderType::StopLimit
            | OrderType::MarketIfTouched
            | OrderType::LimitIfTouched
    );

    let trigger = if is_conditional {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set a limit price on the order (order.price(...)) before adding it to the batch.
  2. Check order.price().is_some() for limit-type orders before calling batch_add_via_ws.
  3. If a market-style order was intended, use OrderType::Market so the limit-price requirement does not apply.

Example fix

// before
let order = OrderBuilder::limit(instrument_id, OrderSide::Buy, qty).build();
// after
let order = OrderBuilder::limit(instrument_id, OrderSide::Buy, qty)
    .price(Price::from("27000.00"))
    .build();
Defensive patterns

Strategy: validation

Validate before calling

use nautilus_model::enums::OrderType;
fn batch_limit_order_valid(t: OrderType, price: Option<Price>) -> bool {
    !matches!(t, OrderType::Limit | OrderType::StopLimit | OrderType::LimitIfTouched)
        || price.is_some()
}

Type guard

fn has_price(order: &OrderAny) -> bool { order.price().is_some() }

Prevention

When it happens

Trigger: Calling batch_add_via_ws with an order of OrderType::Limit, StopLimit, or LimitIfTouched whose order.price() is None (e.g. a Limit order built without a price, or a price passed as a trigger price only).

Common situations: Submitting stop-limit orders where only the trigger price was set and the limit price was forgotten; porting code from market-order flows to batch flows; programmatic order factories that default prices to None.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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