nautechsystems/nautilus_trader · error

Trailing offset type not set

Error message

Trailing offset type not set

What it means

OrderBuilder accumulates optional fields via fluent setters and unwraps them in getters during build(). get_trailing_offset_type() panics because trailing_offset_type was never set with .trailing_offset_type(...) before build() was called. It is a programmer-error guard ensuring trailing-stop orders always carry a defined TrailingOffsetType.

Source

Thrown at crates/model/src/orders/builder.rs:257

    // ----------- 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
    }

    fn get_time_in_force(&self) -> TimeInForce {
        self.time_in_force.unwrap_or(TimeInForce::Gtc)
    }

    // ----------- ExpireTime ----------
    pub fn expire_time(&mut self, expire_time: UnixNanos) -> &mut Self {
        self.expire_time = Some(expire_time);
        self
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Call .trailing_offset_type(TrailingOffsetType::BasisPoints /* or Price, Ticks, etc. */) on the builder before build()
  2. If the order is not a trailing order, verify build() is only reached with a trailing_offset_type set when the order type requires one (e.g. OrderType::TrailingStopMarket)
  3. Source the value from strategy config and fail fast at config-load time if absent

Example fix

// before
let order = OrderBuilder::new(...)
    .order_type(OrderType::TrailingStopMarket)
    .build();
// after
let order = OrderBuilder::new(...)
    .order_type(OrderType::TrailingStopMarket)
    .trailing_offset_type(TrailingOffsetType::BasisPoints)
    .build();
Defensive patterns

Strategy: validation

Validate before calling

// Rust: before build()
assert!(order_type != OrderType::TrailingStopMarket || builder_has_trailing_offset_type(&builder),
    "trailing offset type required for trailing orders");

Type guard

fn has_trailing_offset(b: &OrderBuilder) -> bool { /* expose/peek trailing_offset_type.is_some() */ }

Prevention

When it happens

Trigger: Calling OrderBuilder::build() for an order configured as a trailing-stop / trailing-stop-market (or otherwise relying on trailing offset) without first invoking builder.trailing_offset_type(TrailingOffsetType::...).

Common situations: Copying builder setup code between order types and dropping the trailing_offset_type line; wiring builder fields from config where the trailing-offset enum is missing from strategy config; refactoring that renamed the setter but left the call site unset.

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/b1cac01c9844fe05. Report an issue: GitHub.