nautechsystems/nautilus_trader · error
Trailing offset not set
Error message
Trailing offset not set
What it means
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.
Source
Thrown at crates/model/src/orders/builder.rs:246
// ----------- LimitOffset ----------
pub fn limit_offset(&mut self, limit_offset: Decimal) -> &mut Self {
self.limit_offset = Some(limit_offset);
self
}
fn get_limit_offset(&self) -> Decimal {
self.limit_offset.expect("Limit offset not set")
}
// ----------- TrailingOffset ----------
pub fn trailing_offset(&mut self, trailing_offset: Decimal) -> &mut Self {
self.trailing_offset = Some(trailing_offset);
self
}
fn get_trailing_offset(&self) -> Decimal {
self.trailing_offset.expect("Trailing offset not set")
}
// ----------- TrailingOffsetType ----------
pub fn trailing_offset_type(&mut self, trailing_offset_type: TrailingOffsetType) -> &mut Self {
self.trailing_offset_type = Some(trailing_offset_type);
self
}
fn get_trailing_offset_type(&self) -> TrailingOffsetType {
self.trailing_offset_type
.expect("Trailing offset type not set")
}
// ----------- TimeInForce ----------
pub fn time_in_force(&mut self, time_in_force: TimeInForce) -> &mut Self {
self.time_in_force = Some(time_in_force);
self
}View on GitHub (pinned to 18893faf8b)
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.
Example fix
// before
let order = OrderTestBuilder::new(OrderType::TrailingStopMarket).instrument_id(id).quantity(qty).build();
// after
let order = OrderTestBuilder::new(OrderType::TrailingStopMarket)
.instrument_id(id)
.quantity(qty)
.trailing_offset(Decimal::from(100))
.build(); Defensive patterns
Strategy: validation
Validate before calling
if matches!(order_type, OrderType::TrailingStopMarket | OrderType::TrailingStopLimit) {
assert!(trailing_offset.is_some(), "trailing_offset required for {:?}", order_type);
}
builder.trailing_offset(trailing_offset.unwrap()).build(); Type guard
fn order_type_needs_trailing_offset(t: OrderType) -> bool {
matches!(t, OrderType::TrailingStopMarket | OrderType::TrailingStopLimit)
} Try / catch
// validate before build assert!(trailing_offset.is_some() || !order_type_needs_trailing_offset(order_type));
Prevention
- 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.
When it happens
Trigger: Building a trailing stop order via OrderTestBuilder without chaining .trailing_offset(Decimal) before build().
Common situations: 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.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/9826bd2367a987bd.
Report an issue: GitHub.