nautechsystems/nautilus_trader · error
unsupported Nautilus order type for Lighter: {e}
Error message
unsupported Nautilus order type for Lighter: {e} What it means
nautilus_to_lighter_order_type converts a Nautilus OrderType into a LighterOrderType discriminant; unsupported order types fail conversion and are wrapped in this error. Lighter only supports a subset of Nautilus order types for CreateOrder tx bodies.
Source
Thrown at crates/adapters/lighter/src/websocket/dispatch.rs:2036
match tif {
TimeInForce::Ioc => Ok(LighterTimeInForce::ImmediateOrCancel),
TimeInForce::Fok => anyhow::bail!(
"Lighter has no fill-or-kill TIF; reject FOK at the strategy or use IOC explicitly",
),
TimeInForce::Gtc | TimeInForce::Day | TimeInForce::Gtd => {
Ok(LighterTimeInForce::GoodTillTime)
}
other => anyhow::bail!("Lighter does not support TimeInForce::{other:?}"),
}
}
/// Translate a Nautilus [`OrderType`] into the venue's [`LighterOrderType`]
/// discriminant for use in `CreateOrder` tx bodies.
pub(crate) fn nautilus_to_lighter_order_type(
order_type: OrderType,
) -> anyhow::Result<LighterOrderType> {
LighterOrderType::try_from(order_type)
.map_err(|e| anyhow::anyhow!("unsupported Nautilus order type for Lighter: {e}"))
}
/// Compute the venue-side `order_expiry` (millis) for a Nautilus order.
///
/// - `MARKET`: `ORDER_EXPIRY_IOC` (`0`) because it has no resting trigger
/// lifetime.
/// - Conditional orders: positive expiry from `GTD` or the default GTC window.
/// Lighter uses `TimeInForce` as the post-trigger execution instruction,
/// while `OrderExpiry` controls how long the trigger can rest.
/// - `Gtd` with an explicit expire_time: the millisecond timestamp, provided
/// it is within the venue's 5-minute to 30-day lifetime range.
/// - `Ioc` / `Fok`: `ORDER_EXPIRY_IOC` (`0`): Lighter requires this exact
/// value for IOC semantics; any other value is rejected by the sequencer.
/// - `Gtc` / `Day` / `Gtd` without expiry: `now_ms + ORDER_EXPIRY_DEFAULT_GTC_MS`.
/// The venue rejects `-1` for these TIFs with `21711 invalid expiry`.
pub(crate) fn order_expiry_for(
order_type: OrderType,
tif: &TimeInForce,View on GitHub (pinned to 18893faf8b)
Solutions
- Use only supported order types with Lighter: LIMIT and MARKET.
- Emulate unsupported types client-side (e.g. manage stop triggers in the strategy and submit LIMIT/MARKET on trigger).
- Check the LighterOrderType::try_from(OrderType) implementation for the exact supported set before submitting.
Example fix
// before order_factory.limit(...) // or market(...) only for Lighter // after: unsupported // order_factory.stop_limit(...) -> error; replace with client-side trigger + limit submit
Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED: &[OrderType] = &[OrderType::Limit, OrderType::Market];
anyhow::ensure!(SUPPORTED.contains(&order_type), "order type {order_type} unsupported on Lighter"); Prevention
- Submit only LIMIT or MARKET orders to Lighter
- Implement stop/trailing logic client-side
- Review LighterOrderType::try_from(OrderType) for the supported set
When it happens
Trigger: Submitting an order whose OrderType (e.g. STOP_LIMIT, TRAILING_STOP_MARKET, or other non-Lighter types) has no TryFrom<OrderType> mapping to LighterOrderType.
Common situations: Strategy code written for venues with rich order types being ported to Lighter; defaults emitting LIMIT only sometimes and STOP variants other times; version drift adding new Nautilus order types.
Related errors
- Unsupported order type {other:?} for Deribit
- Unsupported order type for Betfair: {other:?}
- Unsupported order type for Binance Futures: {order_type:?}
- MarketToLimit order type is not supported by BitMEX
- unsupported order type for Bybit: {order_type}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e30d471b2fcaabbb.
Report an issue: GitHub.