nautechsystems/nautilus_trader · error · anyhow::Error

Conditional orders require a trigger price for Hyperliquid:

Error message

Conditional orders require a trigger price for Hyperliquid: {order.order_type():?}

What it means

Conditional order types on Hyperliquid (StopMarket, StopLimit, MarketIfTouched, LimitIfTouched) are mapped to venue trigger orders, which require a trigger price. If such an order is submitted without one, the adapter rejects it with this error naming the order type.

Source

Thrown at crates/adapters/hyperliquid/src/execution.rs:2742

        if !matches!(order.order_type(), OrderType::Market | OrderType::Limit) {
            anyhow::bail!(
                "Trigger order types are not supported for Hyperliquid HIP-4 outcomes: \
                 {symbol} (received {:?})",
                order.order_type()
            );
        }
    }

    if matches!(
        order.order_type(),
        OrderType::StopMarket
            | OrderType::StopLimit
            | OrderType::MarketIfTouched
            | OrderType::LimitIfTouched
    ) && order.trigger_price().is_none()
    {
        anyhow::bail!(
            "Conditional orders require a trigger price for Hyperliquid: {:?}",
            order.order_type()
        );
    }

    if matches!(
        order.order_type(),
        OrderType::Limit | OrderType::StopLimit | OrderType::LimitIfTouched
    ) && order.price().is_none()
    {
        anyhow::bail!(
            "Limit orders require a limit price for Hyperliquid: {:?}",
            order.order_type()
        );
    }

    Ok(())
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Provide a trigger_price when constructing the StopMarket/StopLimit/MarketIfTouched/LimitIfTouched order.
  2. Validate the order in the strategy before submission (assert trigger_price().is_some() for conditional types).
  3. Fix order-construction helpers to require a trigger parameter for conditional types.
  4. If the order should be unconditional, use Market or Limit instead.

Example fix

// before
let order = factory.stop_market(instrument_id, side, qty); // no trigger
exec_client.submit_order(&order).await?;
// after
let order = factory.stop_market_instrument(instrument_id, side, qty, trigger_price); // trigger set
exec_client.submit_order(&order).await?;
Defensive patterns

Strategy: validation

Validate before calling

fn has_trigger(order: &OrderAny) -> bool {
    !matches!(order.order_type(), OrderType::StopMarket | OrderType::StopLimit
        | OrderType::MarketIfTouched | OrderType::LimitIfTouched)
        || order.trigger_price().is_some()
}

Prevention

When it happens

Trigger: submit_order with OrderType in {StopMarket, StopLimit, MarketIfTouched, LimitIfTouched} where order.trigger_price() is None — the order was built without a trigger price.

Common situations: Order factory default-constructed conditional orders without setting the trigger; a bug in strategy code assuming trigger_price defaults to the limit/market price; orders deserialized from external config missing the trigger field.

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/1991ec25489cf8b7. Report an issue: GitHub.