{"record":{"id":"8c00aa86224d9fc9","repo":"nautechsystems/nautilus_trader","slug":"limit-orders-require-a-price","errorCode":null,"errorMessage":"Limit orders require a price","messagePattern":"Limit orders require a price","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/hyperliquid/src/common/parse.rs","lineNumber":539,"sourceCode":"            raw.normalize()\n        }\n    } else if matches!(order_type, OrderType::Market) {\n        Decimal::ZERO\n    } else if matches!(\n        order_type,\n        OrderType::StopMarket | OrderType::MarketIfTouched\n    ) {\n        match order.trigger_price() {\n            Some(tp) => {\n                let base = tp.as_decimal().normalize();\n                let derived = derive_limit_from_trigger(base, is_buy, slippage_bps);\n                let sig_rounded = round_to_sig_figs(derived, 5);\n                clamp_price_to_precision(sig_rounded, price_decimals, is_buy).normalize()\n            }\n            None => Decimal::ZERO,\n        }\n    } else {\n        anyhow::bail!(\"Limit orders require a price\")\n    };\n\n    let size_decimal = order.quantity().as_decimal().normalize();\n\n    // Determine order kind based on order type\n    let kind = match order_type {\n        OrderType::Market => HyperliquidExchangeOrderKind::Limit {\n            limit: HyperliquidExchangeLimitParams {\n                tif: HyperliquidExchangeTif::Ioc,\n            },\n        },\n        OrderType::Limit => {\n            let tif =\n                time_in_force_to_hyperliquid_tif(order.time_in_force(), order.is_post_only())?;\n            HyperliquidExchangeOrderKind::Limit {\n                limit: HyperliquidExchangeLimitParams { tif },\n            }\n        }","sourceCodeStart":521,"sourceCodeEnd":557,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/hyperliquid/src/common/parse.rs#L521-L557","documentation":"When converting a Nautilus order to a Hyperliquid exchange request, limit-type orders must carry a limit price; the price is required to build Hyperliquid's limit px field. The adapter bails with this message when order.price() returns None for a Limit (or StopLimit's limit component), since it cannot derive a valid exchange price.","triggerScenarios":"Submitting or modifying a Limit order (via submit_order, submit_orders, order_request, modify_order) where the order was constructed without a price — e.g. order_factory.limit called without a price argument or with a null/None price propagated from upstream logic.","commonSituations":"Programmatic order construction where price is filled in later but the order is submitted before being set; ported strategy code from a venue where marketable-limit semantics allowed missing prices; deserialized orders from a message bus missing optional price fields.","solutions":["Set a price on the limit order before submission: construct with order_factory.limit(instrument_id, side, quantity, price).","Verify the order-building code path actually assigns the computed price (e.g. mid/market-adjusted price) before calling submit_order.","Add a pre-submit assertion that limit orders have Some(price) so failures surface at the strategy layer with context.","If a marketable order was intended, submit a Market order type instead of a priceless Limit."],"exampleFix":"// before\nlet order = order_factory.limit(instrument_id, OrderSide::Buy, qty, None);\n// after\nlet price = Price::from(\"42000.0\");\nlet order = order_factory.limit(instrument_id, OrderSide::Buy, qty, Some(price));","handlingStrategy":"validation","validationCode":"if order.order_type().is_limit() && order.price().is_none() {\n    return Err(anyhow::anyhow!(\"limit order {} missing price\", order.client_order_id()));\n}\n// run this before adapter.submit_order / modify_order","typeGuard":null,"tryCatchPattern":"match adapter.submit_order(order).await {\n    Err(e) if e.to_string().contains(\"Limit orders require a price\") => {\n        log::error!(\"order built without price; fix order factory call\");\n        Err(e)\n    }\n    r => r,\n}","preventionTips":["Always pass an explicit price to order_factory.limit","Assert limit orders carry a price in a pre-submit sanity check","Ensure price-computation code runs before order submission, not after"],"tags":["hyperliquid","orders","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"}