{"record":{"id":"10c500e7db844eee","repo":"nautechsystems/nautilus_trader","slug":"stop-limit-orders-require-a-trigger-price","errorCode":null,"errorMessage":"Stop limit orders require a trigger price","messagePattern":"Stop limit orders require a trigger price","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/hyperliquid/src/common/parse.rs","lineNumber":595,"sourceCode":"        }\n        OrderType::StopLimit => {\n            if let Some(trigger_price) = order.trigger_price() {\n                let raw = trigger_price.as_decimal();\n                let trigger_price_decimal = if should_normalize_prices {\n                    normalize_price(raw, price_decimals).normalize()\n                } else {\n                    raw.normalize()\n                };\n                let tpsl = determine_tpsl_type(order_type, order_side, trigger_price_decimal, None);\n                HyperliquidExchangeOrderKind::Trigger {\n                    trigger: HyperliquidExchangeTriggerParams {\n                        is_market: false,\n                        trigger_px: trigger_price_decimal,\n                        tpsl,\n                    },\n                }\n            } else {\n                anyhow::bail!(\"Stop limit orders require a trigger price\")\n            }\n        }\n        OrderType::MarketIfTouched => {\n            if let Some(trigger_price) = order.trigger_price() {\n                let raw = trigger_price.as_decimal();\n                let trigger_price_decimal = if should_normalize_prices {\n                    normalize_price(raw, price_decimals).normalize()\n                } else {\n                    raw.normalize()\n                };\n                HyperliquidExchangeOrderKind::Trigger {\n                    trigger: HyperliquidExchangeTriggerParams {\n                        is_market: true,\n                        trigger_px: trigger_price_decimal,\n                        tpsl: HyperliquidExchangeTpSl::Tp,\n                    },\n                }\n            } else {","sourceCodeStart":577,"sourceCodeEnd":613,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/hyperliquid/src/common/parse.rs#L577-L613","documentation":"StopLimit orders require both a trigger price (to arm the order) and a limit price (to execute it). The adapter bails with this message when order.trigger_price() is None for a StopLimit order, because Hyperliquid's trigger order request needs trigger_px to construct the order.","triggerScenarios":"Submitting or modifying a StopLimit order through submit_order, submit_orders, order_request, or modify_order where the order lacks a trigger price — construction with order_factory.limit(...).to_stop_limit style helpers or deserialization that dropped the optional trigger_price field.","commonSituations":"Configured stop-limit strategies where the trigger offset was never resolved (e.g. based on an indicator value not yet computed), orders persisted/reloaded losing optional fields, or copy-pasted order factory calls omitting the trigger parameter.","solutions":["Pass a trigger price when building the StopLimit order (order_factory.stop_limit(..., trigger_price)).","Ensure the trigger-computation step runs before order creation and yields a valid price.","Add pre-submit validation requiring Some(trigger_price) for StopLimit and StopMarket orders.","If only a limit price was intended without a trigger, submit a plain Limit order instead."],"exampleFix":"// before\nlet order = order_factory.stop_limit(instrument_id, side, qty, price, None); // no trigger\n// after\nlet trigger = Price::from(\"41000.0\");\nlet order = order_factory.stop_limit(instrument_id, side, qty, price, Some(trigger));","handlingStrategy":"validation","validationCode":"if order.order_type() == OrderType::StopLimit\n    && (order.trigger_price().is_none() || order.price().is_none()) {\n    return Err(anyhow::anyhow!(\"stop limit {} needs both trigger and limit price\", order.client_order_id()));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass both trigger_price and limit price to order_factory.stop_limit","Resolve indicator-based triggers before constructing the order","Validate all trigger-type orders carry trigger prices in a pre-submit check"],"tags":["hyperliquid","orders","stop-order","missing-field","rust"],"backgroundTag":"missing-required-argument","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}