nautechsystems/nautilus_trader · error
Lighter market orders support only TimeInForce::Gtc or TimeI
Error message
Lighter market orders support only TimeInForce::Gtc or TimeInForce::Ioc, was TimeInForce::{other:?} What it means
The Lighter adapter rejects Nautilus market orders whose TimeInForce is not GTC or IOC. Lighter market orders are always immediate-or-cancel on the venue, so GTC/IOC map to ImmediateOrCancel, while any other TIF (e.g. Day, Gtd, AtTheClose) has no venue representation and is rejected at order-submission translation time with this bail! error.
Source
Thrown at crates/adapters/lighter/src/websocket/dispatch.rs:1995
/// FOK ("fill or kill") is rejected because Lighter has no native
/// fill-or-kill primitive: routing FOK as IOC would let a partial fill
/// satisfy the request, violating the FOK guarantee.
pub(crate) fn nautilus_to_lighter_tif(
order_type: OrderType,
tif: TimeInForce,
post_only: bool,
) -> anyhow::Result<LighterTimeInForce> {
if post_only {
return Ok(LighterTimeInForce::PostOnly);
}
if order_type == OrderType::Market {
return match tif {
TimeInForce::Gtc | 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",
),
other => anyhow::bail!(
"Lighter market orders support only TimeInForce::Gtc or TimeInForce::Ioc, was TimeInForce::{other:?}",
),
};
}
if is_conditional_market_order(order_type) {
return match tif {
TimeInForce::Gtc | TimeInForce::Day | TimeInForce::Gtd => {
Ok(LighterTimeInForce::ImmediateOrCancel)
}
TimeInForce::Ioc => anyhow::bail!(
"Lighter conditional market orders require a positive expiry; Nautilus IOC cannot be represented because the venue uses IOC for post-trigger execution",
),
TimeInForce::Fok => anyhow::bail!(
"Lighter has no fill-or-kill TIF; reject FOK at the strategy or use IOC explicitly",
),
other => anyhow::bail!(
"Lighter conditional market orders do not support TimeInForce::{other:?}",View on GitHub (pinned to 18893faf8b)
Solutions
- Change the market order to TimeInForce::Gtc or TimeInForce::Ioc before submission
- If day/expiring behavior is required, implement a strategy-level timer to cancel unexecuted IOC orders instead of relying on venue TIF
- Validate orders in a strategy pre-submit hook and log/reject unsupported TIFs early
Example fix
// before order = order_factory.market(instrument_id, side, qty, tif=TimeInForce.DAY) // after order = order_factory.market(instrument_id, side, qty, tif=TimeInForce.GTC)
Defensive patterns
Strategy: validation
Validate before calling
// Rust
fn is_lighter_market_tif(tif: TimeInForce) -> bool {
matches!(tif, TimeInForce::Gtc | TimeInForce::Ioc)
}
assert!(is_lighter_market_tif(order.tif()), "Lighter market order requires GTC or IOC"); Type guard
fn is_gtc_or_ioc(tif: TimeInForce) -> bool {
matches!(tif, TimeInForce::Gtc | TimeInForce::Ioc)
} Prevention
- Default market-order TIF to IOC for Lighter strategies
- Add a pre-submit assertion on order TIF
- Document venue TIF support in strategy config schemas
When it happens
Trigger: Submitting an OrderType::Market to the Lighter adapter with TimeInForce::Day, TimeInForce::Gtd, or any TIF other than Gtc/Ioc (Fok hits its own earlier match arm). This happens in the TIF translation path in nautilus_to_lighter_tif called during CreateOrder tx construction.
Common situations: Strategy defaults or config files that set tif=DAY or GTD on all orders; templates built for equity/futures venues where Day orders are valid; porting a strategy from another adapter without reviewing per-order TIF.
Related errors
- Lighter conditional market orders require a positive expiry;
- Lighter conditional market orders do not support TimeInForce
- Lighter does not support TimeInForce::{other:?}
- {e}
- Invalid order side: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/9403c6248377285d.
Report an issue: GitHub.