nautechsystems/nautilus_trader · error

generate_order_status_report requires instrument_id

Error message

generate_order_status_report requires instrument_id

What it means

OKXExecutionClient::generate_order_status_report requires the command to carry an instrument_id so it can resolve the OKX instrument (instId) for the order query. If cmd.instrument_id is None, the adapter bails with anyhow before making any request. This is a guard against issuing an OKX order-detail lookup that cannot name an instrument.

Source

Thrown at crates/adapters/okx/src/execution.rs:1990

        Ok(())
    }

    fn reset(&mut self) -> anyhow::Result<()> {
        self.begin_generation_shutdown();
        Ok(())
    }

    fn dispose(&mut self) -> anyhow::Result<()> {
        self.begin_generation_shutdown();
        Ok(())
    }

    async fn generate_order_status_report(
        &self,
        cmd: &GenerateOrderStatusReport,
    ) -> anyhow::Result<Option<OrderStatusReport>> {
        let Some(instrument_id) = cmd.instrument_id else {
            anyhow::bail!("generate_order_status_report requires instrument_id");
        };

        if cmd.client_order_id.is_none() && cmd.venue_order_id.is_none() {
            anyhow::bail!(
                "generate_order_status_report requires client_order_id or venue_order_id"
            );
        }

        let order_state = {
            let cache = self.core.cache();
            cmd.client_order_id.and_then(|client_order_id| {
                cache
                    .order(&client_order_id)
                    .map(|order| CachedQueryOrderState {
                        order_type: order.order_type(),
                        venue_order_id: order.venue_order_id(),
                    })
            })

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set instrument_id on the GenerateOrderStatusReport before calling generate_order_status_report
  2. If only a venue_order_id is known, resolve the instrument_id first (from cache or order state) and pass it explicitly
  3. When the instrument is genuinely unknown, skip this report or look the order up via a venue-wide order list endpoint instead of the single-order detail path

Example fix

// before
let cmd = GenerateOrderStatusReport { instrument_id: None, client_order_id: Some(coid), .. };
// after
let cmd = GenerateOrderStatusReport { instrument_id: Some(instrument_id), client_order_id: Some(coid), .. };
Defensive patterns

Strategy: validation

Validate before calling

if cmd.instrument_id.is_none() {
    return Err(anyhow::anyhow!("cannot generate order status report without instrument_id"));
}

Type guard

fn has_instrument_id(cmd: &GenerateOrderStatusReport) -> bool {
    cmd.instrument_id.is_some()
}

Try / catch

match exec.generate_order_status_report(&cmd).await {
    Ok(Some(report)) => { /* use report */ }
    Ok(None) => { /* order not found */ }
    Err(e) if e.to_string().contains("requires instrument_id") => { /* fix command and retry */ }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling generate_order_status_report (directly or via the execution engine's report generation / assert_bootstrap_reports reconciliation) with a GenerateOrderStatusReport whose instrument_id field is None.

Common situations: Building a report request from data where the instrument was never parsed (e.g. reconstructing a command from a venue_order_id alone during reconciliation or bootstrap), or wiring the command struct by hand and forgetting to fill instrument_id.

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