{"record":{"id":"96b1eb71eb409b9f","repo":"nautechsystems/nautilus_trader","slug":"lighter-has-no-fill-or-kill-tif-reject-fok-at-the","errorCode":null,"errorMessage":"Lighter has no fill-or-kill TIF; reject FOK at the strategy or use IOC explicitly","messagePattern":"Lighter has no fill-or-kill TIF; reject FOK at the strategy or use IOC explicitly","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/websocket/dispatch.rs","lineNumber":1992,"sourceCode":"/// execution instruction, but their trigger lifetime is controlled by a\n/// positive `OrderExpiry`.\n///\n/// FOK (\"fill or kill\") is rejected because Lighter has no native\n/// fill-or-kill primitive: routing FOK as IOC would let a partial fill\n/// satisfy the request, violating the FOK guarantee.\npub(crate) fn nautilus_to_lighter_tif(\n    order_type: OrderType,\n    tif: TimeInForce,\n    post_only: bool,\n) -> anyhow::Result<LighterTimeInForce> {\n    if post_only {\n        return Ok(LighterTimeInForce::PostOnly);\n    }\n\n    if order_type == OrderType::Market {\n        return match tif {\n            TimeInForce::Gtc | TimeInForce::Ioc => Ok(LighterTimeInForce::ImmediateOrCancel),\n            TimeInForce::Fok => anyhow::bail!(\n                \"Lighter has no fill-or-kill TIF; reject FOK at the strategy or use IOC explicitly\",\n            ),\n            other => anyhow::bail!(\n                \"Lighter market orders support only TimeInForce::Gtc or TimeInForce::Ioc, was TimeInForce::{other:?}\",\n            ),\n        };\n    }\n\n    if is_conditional_market_order(order_type) {\n        return match tif {\n            TimeInForce::Gtc | TimeInForce::Day | TimeInForce::Gtd => {\n                Ok(LighterTimeInForce::ImmediateOrCancel)\n            }\n            TimeInForce::Ioc => anyhow::bail!(\n                \"Lighter conditional market orders require a positive expiry; Nautilus IOC cannot be represented because the venue uses IOC for post-trigger execution\",\n            ),\n            TimeInForce::Fok => anyhow::bail!(\n                \"Lighter has no fill-or-kill TIF; reject FOK at the strategy or use IOC explicitly\",","sourceCodeStart":1974,"sourceCodeEnd":2010,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/websocket/dispatch.rs#L1974-L2010","documentation":"Raised when translating an order's time-in-force for a Lighter market order with TimeInForce::Fok. Lighter's market orders only support GTC (mapped to ImmediateOrCancel) and IOC; there is no fill-or-kill TIF on the venue, so FOK is rejected with this guidance message.","triggerScenarios":"Submitting a Lighter MARKET order with tif = TimeInForce::Fok — e.g. a strategy configured for FOK market entries, or code defaulting market orders to FOK — hits this bail in the TIF translation before the order reaches the exchange.","commonSituations":"Porting a strategy from another venue (e.g. Binance/Crypto.com) that supports FOK without adjusting TIF for Lighter; backtest code that assumes universal FOK support; a default TimeInForce::Fok in an order factory configuration.","solutions":["Change the strategy/submit call to use TimeInForce::Ioc for market orders (nearest semantics to FOK on Lighter).","Use a LIMIT PostOnly or IOC order if fill-all-or-nothing semantics are mandatory; emulate FOK at the strategy level (cancel unfilled remainder).","Update the order factory/emulator config so market orders default to GTC or IOC.","Add pre-submit validation in your strategy that rejects FOK for Lighter instruments.","If FOK support appears in a newer Lighter API, upgrade the adapter and revisit this mapping."],"exampleFix":"// before\nlet order = order_factory.market(\n    instrument_id, OrderSide::Buy, qty,\n    TimeInForce::Fok, None, // rejected by Lighter\n);\n\n// after\nlet order = order_factory.market(\n    instrument_id, OrderSide::Buy, qty,\n    TimeInForce::Ioc, None,\n);","handlingStrategy":"validation","validationCode":"// reject FOK market orders before submission\nif order_type == OrderType::Market && tif == TimeInForce::Fok {\n    return Err(\"Lighter market orders do not support FOK; use IOC\".into());\n}","typeGuard":null,"tryCatchPattern":"match translate_tif(order_type, tif) {\n    Err(e) if e.to_string().contains(\"fill-or-kill\") => {\n        log::warn!(\"downgrading FOK to IOC for Lighter\");\n        translate_tif(order_type, TimeInForce::Ioc)?\n    }\n    r => r?,\n}","preventionTips":["Configure strategies to use IOC/GTC for Lighter market orders","Audit order-factory defaults for venue-incompatible TIFs","Emulate FOK semantics at the strategy layer (cancel remainder)","Check venue TIF support before porting strategies from other exchanges"],"tags":["orders","time-in-force","validation","adapter"],"backgroundTag":"unsupported-enum-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}