nautechsystems/nautilus_trader · error · anyhow::Error

actual order symbol mismatch: expected

Error message

actual order symbol mismatch: expected {}, was {}

What it means

During algo order reconciliation the symbol on the parent algo record must equal the symbol on the matched actual (child) order. A mismatch indicates the two records describe different instruments, so the pair cannot be merged into one order report.

Solutions

  1. Verify the algo and actual records come from the same stream/symbol; refetch the order via REST.
  2. Fix stream multiplexing so per-symbol messages are not crossed.
  3. Correct fixture/test data so symbols agree.

Example fix

// before
// algo record symbol: BTCUSDT, actual sub-order symbol: ETHUSDT
// after
// ensure both records carry the same symbol, e.g. BTCUSDT, or re-fetch correct data
Defensive patterns

Strategy: try-catch

Validate before calling

fn same_symbol(algo_sym: &str, actual_sym: &str) -> bool { algo_sym == actual_sym }

Try / catch

match result {
    Err(e) if e.to_string().contains("actual order symbol mismatch") => {
        tracing::error!("algo/actual symbol mismatch in stream data: {e}");
    }
    r => r?,
}

Prevention

When it happens

Trigger: Parsing an algo order update where self.symbol (the algo record's symbol) differs from actual.symbol of the matched sub-order, e.g. 'BTCUSDT' vs 'ETHUSDT' in the same payload.

Common situations: Malformed or cross-wired exchange payloads; buggy fixture data; a matching routine that pairs records from different symbols after a stream hiccup or multiplexing error.

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

Appendix: source

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

        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
            );
        }

        let mut report = self.to_order_status_report(
            account_id,
            instrument_id,
            price_precision,

View on GitHub (pinned to 18893faf8b)