nautechsystems/nautilus_trader · error · anyhow::Error

command client order ID {} does not match cached order {}

Error message

command client order ID {} does not match cached order {}

What it means

`validate_cancel_order_target` uses `anyhow::ensure!` to verify that the `CancelOrder` command's `client_order_id` equals the `client_order_id` of the cached order it was resolved against. If they differ, an internal bookkeeping inconsistency exists — the cancel command was matched to the wrong cached order — and this error is returned instead of sending a cancel to IB for the wrong order.

Source

Thrown at crates/adapters/interactive_brokers/src/execution/core.rs:2106

            symbol = exec_data.contract.symbol.as_str(),
            sec_type = ?exec_data.contract.security_type,
            exchange = exec_data.contract.exchange.as_str(),
            primary_exchange = exec_data.contract.primary_exchange.as_str(),
            local_symbol = exec_data.contract.local_symbol.as_str(),
            con_id = exec_data.contract.contract_id,
            order_id = exec_data.execution.order_id,
            order_ref = exec_data.execution.order_reference.as_str(),
            execution_id = exec_data.execution.execution_id.as_str(),
            error = %error,
            "Failed to parse IBKR historical fill report",
        );
    }

    fn validate_cancel_order_target(
        cmd: &CancelOrder,
        target_order: &OrderAny,
    ) -> anyhow::Result<()> {
        anyhow::ensure!(
            cmd.client_order_id == target_order.client_order_id(),
            "command client order ID {} does not match cached order {}",
            cmd.client_order_id,
            target_order.client_order_id()
        );
        anyhow::ensure!(
            cmd.instrument_id == target_order.instrument_id(),
            "command instrument ID {} does not match cached order {}",
            cmd.instrument_id,
            target_order.instrument_id()
        );

        // Command actor IDs identify the requester and are not ownership evidence
        if let (Some(command_venue_order_id), Some(target_venue_order_id)) =
            (cmd.venue_order_id.as_ref(), target_order.venue_order_id())
        {
            anyhow::ensure!(
                command_venue_order_id == &target_venue_order_id,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Log both IDs and re-resolve the target order from the cache using `cmd.client_order_id` exactly.
  2. Purge/rebuild the execution cache (reconcile) so cached orders match live client order IDs.
  3. Fix the caller constructing the `CancelOrder` to use the correct client order ID for the target order.

Example fix

// before
let target = cache.order(&some_other_id)?;
validate_cancel_order_target(cmd, &target)?;
// after
let target = cache.order(&cmd.client_order_id)?;
validate_cancel_order_target(cmd, &target)?;
Defensive patterns

Strategy: validation

Validate before calling

// Before sending a CancelOrder, confirm the cached order matches
if let Some(order) = cache.order(&cmd.client_order_id) {
    assert_eq!(order.client_order_id(), cmd.client_order_id, "cache/client_order_id mismatch");
} else {
    return Err(anyhow::anyhow!("no cached order for {}", cmd.client_order_id));
}

Type guard

fn cancel_target_matches(cmd: &CancelOrder, order: &OrderAny) -> bool {
    cmd.client_order_id == order.client_order_id()
}

Try / catch

match validate_cancel_order_target(&cmd, &target_order) {
    Ok(()) => send_cancel_to_ib(&cmd),
    Err(e) => {
        log::error!("cancel target mismatch, rebuilding cache: {e}");
        reconcile_cache_and_retry(&cmd).await?;
    }
}

Prevention

When it happens

Trigger: Calling cancel handling where `cmd.client_order_id` differs from `target_order.client_order_id()`: a stale/mismatched cache lookup, a command constructed with the wrong ID, or duplicated/rotated client order IDs after reconnect.

Common situations: Reconciliation leaving the order cache pointing at a different order; external systems issuing cancels with a recycled or mistyped client order ID; cache corruption or wrong index used to fetch the target order.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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