nautechsystems/nautilus_trader · error

Order detail venue order ID mismatch for {venue_order_id}: r

Error message

Order detail venue order ID mismatch for {venue_order_id}: returned {}

What it means

If the caller supplied a venue_order_id, the adapter additionally checks that the returned order's ordId equals it. A mismatch means the exchange returned a different order than requested under that identifier, so the adapter bails to prevent fabricating a status report for the wrong order.

Source

Thrown at crates/adapters/okx/src/http/client.rs:4407

            [] => return Ok(None),
            [order] => order,
            _ => anyhow::bail!(
                "Order detail returned {} records for one identifier",
                orders.len(),
            ),
        };

        if order.inst_id.as_str() != instrument_id.symbol.inner() {
            anyhow::bail!(
                "Order detail instrument mismatch for {instrument_id}: returned {}",
                order.inst_id,
            );
        }

        if let Some(venue_order_id) = venue_order_id
            && order.ord_id.as_str() != venue_order_id.as_str()
        {
            anyhow::bail!(
                "Order detail venue order ID mismatch for {venue_order_id}: returned {}",
                order.ord_id,
            );
        }

        let ts_init = self.generate_ts_init();
        let mut report = parse_order_status_report(
            order,
            account_id,
            instrument.id(),
            instrument.price_precision(),
            instrument.size_precision(),
            ts_init,
        )?;
        let post_only_rejected = order.state == OKXOrderStatus::Canceled
            && report.filled_qty.is_zero()
            && (order.cancel_source == OKX_POST_ONLY_CANCEL_SOURCE
                || order.cancel_source_reason.contains("POST_ONLY"));

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Refresh the venue_order_id from the exchange (order list / reconciliation) before the detail query
  2. Prefer client_order_id (clOrdId) lookup if the venue order ID is uncertain
  3. Verify the venue_order_id originates from the same instrument/account context as the query
Defensive patterns

Strategy: validation

Validate before calling

// confirm the cached venue_order_id is still current via order list before detail lookup

Type guard

fn venue_id_matches(returned: &str, requested: &VenueOrderId) -> bool {
    returned == requested.as_str()
}

Try / catch

match client.request_order_detail(instrument_id, None, Some(void)).await {
    Ok(r) => { /* use */ }
    Err(e) if e.to_string().contains("venue order ID mismatch") => {
        // refresh venue_order_id from exchange and retry
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: request_order_detail called with venue_order_id V, and OKX returns a record whose ord_id != V (e.g. identifier reused/rotated, or exchange-side id aliasing).

Common situations: Stale venue_order_id cached from a previous session; OKX changing/renaming ordId after order amendments; copy-paste or mapping bugs in reconciliation code.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/bee3084be9d0bab9. Report an issue: GitHub.