nautechsystems/nautilus_trader · error · anyhow::Error

actual order ID mismatch: expected

Error message

actual order ID mismatch: expected {expected_actual_order_id}, was {}

What it means

When reconciling an algo (conditional) order report with the algorithm's actual sub-order, the adapter verifies the reported actual_order_id matches the actual order's order_id string. A mismatch means the paired execution report does not correspond to the expected algo child order, indicating corrupted or mismatched exchange data.

Solutions

  1. Log both IDs and re-fetch the algo order state via REST to reconcile with fresh data.
  2. Check for replayed/duplicate websocket messages and ensure sequence handling.
  3. If in a fixture, correct actual_order_id or actual.order_id so they match.

Example fix

// before
actual_order_id: Some("123"), actual: AlgoSubOrder { order_id: 456, .. }
// after
actual_order_id: Some("456"), actual: AlgoSubOrder { order_id: 456, .. }
Defensive patterns

Strategy: try-catch

Try / catch

match result {
    Err(e) if e.to_string().contains("actual order ID mismatch") => {
        tracing::warn!("algo reconciliation mismatch, refetching via REST");
        // re-fetch algo order state before continuing
    }
    r => r?,
}

Prevention

When it happens

Trigger: Parsing a Binance Futures algo order update where the record's actual_order_id field (non-empty) differs from actual.order_id.to_string(); the executor matched the wrong child order or the exchange payload contains stale/crossed identifiers.

Common situations: Exchange-side data glitches in algo (conditional) order streams; replayed or reordered websocket messages pairing an old actual order with a new algo record; manually constructed test fixtures with inconsistent IDs.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at crates/adapters/binance/src/futures/http/models.rs:1620

    #[expect(clippy::too_many_arguments)]
    pub fn to_order_status_report_with_actual(
        &self,
        actual: &BinanceFuturesOrder,
        account_id: AccountId,
        instrument_id: InstrumentId,
        price_precision: u8,
        size_precision: u8,
        treat_expired_as_canceled: bool,
        ts_init: UnixNanos,
    ) -> anyhow::Result<OrderStatusReport> {
        let expected_actual_order_id = self
            .actual_order_id
            .as_deref()
            .filter(|id| !id.is_empty())
            .context("algo order has no actual_order_id")?;

        if expected_actual_order_id != actual.order_id.to_string() {
            anyhow::bail!(
                "actual order ID mismatch: expected {expected_actual_order_id}, was {}",
                actual.order_id
            );
        }

        if self.symbol != actual.symbol {
            anyhow::bail!(
                "actual order symbol mismatch: expected {}, was {}",
                self.symbol,
                actual.symbol
            );
        }

        if self.side != actual.side {
            anyhow::bail!(
                "actual order side mismatch: expected {:?}, was {:?}",
                self.side,
                actual.side

View on GitHub (pinned to 18893faf8b)