nautechsystems/nautilus_trader · error · anyhow::Error
Limit-if-touched orders require a trigger price
Error message
Limit-if-touched orders require a trigger price
What it means
Hyperliquid Limit-if-Touched (LIT) orders are trigger orders with is_market=false, so a trigger price is mandatory on the exchange. When the adapter maps OrderType::LimitIfTouched and finds order.trigger_price() is None, it cannot populate the trigger_px field and fails with this bail! before any request reaches the venue.
Source
Thrown at crates/adapters/hyperliquid/src/common/parse.rs:633
}
}
OrderType::LimitIfTouched => {
if let Some(trigger_price) = order.trigger_price() {
let raw = trigger_price.as_decimal();
let trigger_price_decimal = if should_normalize_prices {
normalize_price(raw, price_decimals).normalize()
} else {
raw.normalize()
};
HyperliquidExchangeOrderKind::Trigger {
trigger: HyperliquidExchangeTriggerParams {
is_market: false,
trigger_px: trigger_price_decimal,
tpsl: HyperliquidExchangeTpSl::Tp,
},
}
} else {
anyhow::bail!("Limit-if-touched orders require a trigger price")
}
}
_ => anyhow::bail!("Unsupported order type for Hyperliquid: {order_type:?}"),
};
Ok(HyperliquidExchangePlaceOrderRequest {
asset,
is_buy,
price: price_decimal,
size: size_decimal,
reduce_only,
kind,
cloid,
})
}
/// Default slippage buffer in basis points for MARKET orders.
pub const DEFAULT_MARKET_SLIPPAGE_BPS: u32 = 50;View on GitHub (pinned to 18893faf8b)
Solutions
- Pass a trigger_price when creating the LimitIfTouchedOrder (OrderFactory::limit_if_touched).
- Pre-validate that order.trigger_price().is_some() for LimitIfTouched orders before calling submit_order.
- If no trigger is wanted, submit a plain OrderType::Limit order instead.
Example fix
// before
let order = self.order_factory.limit_if_touched(
instrument_id, OrderSide::Sell, quantity, limit_price, None, TimeInForce::Gtc,
);
// after
let order = self.order_factory.limit_if_touched(
instrument_id, OrderSide::Sell, quantity, limit_price, Some(trigger_price), TimeInForce::Gtc,
); Defensive patterns
Strategy: validation
Validate before calling
if matches!(order.order_type(), OrderType::LimitIfTouched) && order.trigger_price().is_none() {
return Err("LIT order submitted to Hyperliquid without trigger price");
} Type guard
fn lit_has_trigger(order: &OrderAny) -> bool {
!matches!(order.order_type(), OrderType::LimitIfTouched) || order.trigger_price().is_some()
} Prevention
- Provide both price and trigger_price when building limit_if_touched orders.
- Validate order completeness in a shared submit wrapper.
- Prefer plain Limit orders when no trigger is intended.
When it happens
Trigger: Submitting or modifying an OrderType::LimitIfTouched order via submit_order/modify_order/order_request where the order was built without a trigger price.
Common situations: Constructing a limit_if_touched order from a factory call omitting the trigger_price argument; orders deserialized or restored from persistence losing their trigger price; porting strategies from venues where LIT trigger is derived implicitly.
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
- Market-if-touched orders require a trigger price
- Conditional order missing trigger price
- Conditional order missing tpsl indicator
- Conditional order missing is_market flag
- Unsupported `OrderSide` for Binance: {value:?}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/951721ca19ce24d2.
Report an issue: GitHub.