nautechsystems/nautilus_trader · error

registered order context for {venue_order_id} contradicts ca

Error message

registered order context for {venue_order_id} contradicts cached order {}

What it means

After individual checks pass, the adapter cross-validates the registered order context against the cached order: client order id, instrument id, side, order type, and time in force must all agree. This ensure! fires when the registered context contradicts the cached order, indicating the registry and cache are out of sync — a serious internal consistency problem.

Source

Thrown at crates/adapters/polymarket/src/execution/reports.rs:176

                anyhow::ensure!(
                    cached_order.instrument_id() == requested_instrument_id,
                    "cached order instrument {} does not match requested instrument {requested_instrument_id}",
                    cached_order.instrument_id(),
                );
            }
        }

        if let Some(context) = context {
            if let Some(requested_instrument_id) = requested_instrument_id {
                anyhow::ensure!(
                    context.identity.instrument_id == requested_instrument_id,
                    "registered order instrument {} does not match requested instrument {requested_instrument_id}",
                    context.identity.instrument_id,
                );
            }

            if let Some(cached_order) = cached_order.as_ref() {
                anyhow::ensure!(
                    context.identity.client_order_id == cached_order.client_order_id()
                        && context.identity.instrument_id == cached_order.instrument_id()
                        && context.identity.order_side == cached_order.order_side()
                        && context.identity.order_type == cached_order.order_type()
                        && context.time_in_force == cached_order.time_in_force(),
                    "registered order context for {venue_order_id} contradicts cached order {}",
                    cached_order.client_order_id(),
                );
            }
        }

        Ok(TargetOrderAuthority {
            client_order_id,
            instrument_id: context
                .map(|value| value.identity.instrument_id)
                .or_else(|| cached_order.as_ref().map(Order::instrument_id)),
            order_side: context
                .map(|value| value.identity.order_side)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Re-register the order context from the cached order so both views agree
  2. Investigate which update path (submit vs modify) skipped syncing cache or registry
  3. Restart/reconnect the adapter to rebuild consistent state
  4. File a bug if the inconsistency arises from normal submit/modify flow

Example fix

// before
// context updated with new TIF, cache order still old TIF -> ensure! fires
// after
let cached = core.cache().order_owned(&coid).context("order not cached")?;
order_contexts.register(void_id, OrderContext::from(&*cached)); // keep registry derived from cache
Defensive patterns

Strategy: validation

Validate before calling

let cached = core.cache().order_owned(&ctx.identity.client_order_id).context("missing cached order")?;
anyhow::ensure!(
    ctx.identity.instrument_id == cached.instrument_id()
        && ctx.identity.order_side == cached.order_side()
        && ctx.identity.order_type == cached.order_type()
        && ctx.time_in_force == cached.time_in_force(),
    "context/cache diverged"
);

Type guard

fn consistent(ctx: &OrderContext, cached: &OrderAny) -> bool {
    ctx.identity.client_order_id == *cached.client_order_id()
        && ctx.identity.instrument_id == *cached.instrument_id()
        && ctx.identity.order_side == cached.order_side()
        && ctx.identity.order_type == cached.order_type()
}

Try / catch

match client.generate_order_status_report_impl(...).await {
    Err(e) if e.to_string().contains("contradicts cached order") => {
        error!("registry/cache divergence — rebuild state before trading");
    }
    other => other?,
}

Prevention

When it happens

Trigger: generate_order_status_report_impl or generate_fill_reports_impl where order_contexts.get(venue_order_id) returns a context whose identity fields (or time_in_force) differ from cache.order_owned(client_order_id) — e.g. after a replace where the context was updated but the cache wasn't, or vice versa.

Common situations: A modify/replace updated only one of registry/cache; concurrent updates raced; a bug in registration wrote wrong side/type/TIF; stale process state after reconnect.

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