{"record":{"id":"9826bd2367a987bd","repo":"nautechsystems/nautilus_trader","slug":"trailing-offset-not-set","errorCode":null,"errorMessage":"Trailing offset not set","messagePattern":"Trailing offset not set","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/orders/builder.rs","lineNumber":246,"sourceCode":"\n    // ----------- LimitOffset ----------\n    pub fn limit_offset(&mut self, limit_offset: Decimal) -> &mut Self {\n        self.limit_offset = Some(limit_offset);\n        self\n    }\n\n    fn get_limit_offset(&self) -> Decimal {\n        self.limit_offset.expect(\"Limit offset not set\")\n    }\n\n    // ----------- TrailingOffset ----------\n    pub fn trailing_offset(&mut self, trailing_offset: Decimal) -> &mut Self {\n        self.trailing_offset = Some(trailing_offset);\n        self\n    }\n\n    fn get_trailing_offset(&self) -> Decimal {\n        self.trailing_offset.expect(\"Trailing offset not set\")\n    }\n\n    // ----------- TrailingOffsetType ----------\n    pub fn trailing_offset_type(&mut self, trailing_offset_type: TrailingOffsetType) -> &mut Self {\n        self.trailing_offset_type = Some(trailing_offset_type);\n        self\n    }\n\n    fn get_trailing_offset_type(&self) -> TrailingOffsetType {\n        self.trailing_offset_type\n            .expect(\"Trailing offset type not set\")\n    }\n\n    // ----------- TimeInForce ----------\n    pub fn time_in_force(&mut self, time_in_force: TimeInForce) -> &mut Self {\n        self.time_in_force = Some(time_in_force);\n        self\n    }","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/orders/builder.rs#L228-L264","documentation":"OrderTestBuilder::get_trailing_offset unwraps Option<Decimal> set via .trailing_offset(...). build() for trailing order types (TrailingStopMarket, TrailingStopLimit) panics with 'Trailing offset not set' when absent.","triggerScenarios":"Building a trailing stop order via OrderTestBuilder without chaining .trailing_offset(Decimal) before build().","commonSituations":"Creating trailing stop tests by copying a stop-order builder and missing the trailing_offset line, or data-driven tests where the offset field is empty for some rows.","solutions":["Add .trailing_offset(Decimal::from(...)) to the builder chain before build().","Pair trailing_offset with the correct trailing_offset_type (basis points vs price) so downstream validation passes.","Use a fixture for trailing orders that always sets the offset."],"exampleFix":"// before\nlet order = OrderTestBuilder::new(OrderType::TrailingStopMarket).instrument_id(id).quantity(qty).build();\n// after\nlet order = OrderTestBuilder::new(OrderType::TrailingStopMarket)\n    .instrument_id(id)\n    .quantity(qty)\n    .trailing_offset(Decimal::from(100))\n    .build();","handlingStrategy":"validation","validationCode":"if matches!(order_type, OrderType::TrailingStopMarket | OrderType::TrailingStopLimit) {\n    assert!(trailing_offset.is_some(), \"trailing_offset required for {:?}\", order_type);\n}\nbuilder.trailing_offset(trailing_offset.unwrap()).build();","typeGuard":"fn order_type_needs_trailing_offset(t: OrderType) -> bool {\n    matches!(t, OrderType::TrailingStopMarket | OrderType::TrailingStopLimit)\n}","tryCatchPattern":"// validate before build\nassert!(trailing_offset.is_some() || !order_type_needs_trailing_offset(order_type));","preventionTips":["Always set .trailing_offset(...) for trailing order types.","Pair it with .trailing_offset_type(...) so semantics (bps vs price) are explicit.","Keep a trailing-order fixture builder with sensible defaults in test utilities."],"tags":["rust","panic","builder","missing-field","testing"],"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"}