nautechsystems/nautilus_trader · error
Instrument ID not set
Error message
Instrument ID not set
What it means
OrderTestBuilder::get_instrument_id unwraps the Option<InstrumentId> set via .instrument_id(...). Calling build() without first setting an instrument id panics with 'Instrument ID not set'. The builder treats required fields as panics rather than Result-returning errors.
Source
Thrown at crates/model/src/orders/builder.rs:155
// ----------- StrategyId ----------
pub fn strategy_id(&mut self, strategy_id: StrategyId) -> &mut Self {
self.strategy_id = Some(strategy_id);
self
}
fn get_strategy_id(&self) -> StrategyId {
self.strategy_id.unwrap_or_else(StrategyId::test_default)
}
// ----------- InstrumentId ----------
pub fn instrument_id(&mut self, instrument_id: InstrumentId) -> &mut Self {
self.instrument_id = Some(instrument_id);
self
}
fn get_instrument_id(&self) -> InstrumentId {
self.instrument_id.expect("Instrument ID not set")
}
// ----------- ClientOrderId ----------
pub fn client_order_id(&mut self, client_order_id: ClientOrderId) -> &mut Self {
self.client_order_id = Some(client_order_id);
self
}
fn get_client_order_id(&self) -> ClientOrderId {
self.client_order_id
.unwrap_or_else(ClientOrderId::test_default)
}
// ----------- OrderSide ----------
pub fn side(&mut self, side: OrderSide) -> &mut Self {
self.side = Some(side);
self
}View on GitHub (pinned to 18893faf8b)
Solutions
- Add .instrument_id(...) to the builder chain before calling build().
- Centralize a helper that supplies a default test instrument id.
- Check that the value passed is a valid InstrumentId::from("BTCUSDT.BINANCE")-style identifier, not just present.
Example fix
// before
let order = OrderTestBuilder::new(OrderType::Limit).quantity(qty).build();
// after
let order = OrderTestBuilder::new(OrderType::Limit)
.instrument_id(InstrumentId::from("BTCUSDT.BINANCE"))
.quantity(qty)
.build(); Defensive patterns
Strategy: validation
Validate before calling
let mut b = OrderTestBuilder::new(OrderType::Limit); assert!(instrument_id.is_some(), "instrument_id must be set before build()"); b.instrument_id(instrument_id.unwrap()).build();
Type guard
fn requires_instrument_id(b: &OrderTestBuilder) -> bool { true } // every build() needs it; assert presence in your fixture instead Try / catch
// builder panics are not catchable panics you should rely on; validate inputs before build assert!(instrument_id.is_some());
Prevention
- Always include .instrument_id(...) as the first link in the builder chain.
- Wrap OrderTestBuilder in a project-local fixture with required defaults.
- Review builder chains after refactors to ensure required fields were not dropped.
When it happens
Trigger: Calling OrderTestBuilder::build() without chaining .instrument_id(InstrumentId) beforehand; the panic is raised inside get_instrument_id during build.
Common situations: Test code copying an existing builder invocation and forgetting the instrument_id line, or refactoring helpers where the instrument id became conditional.
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/e5ed937c88906d8c.
Report an issue: GitHub.