nautechsystems/nautilus_trader · error

cached Lighter order {cloid} does not match venue order ID {

Error message

cached Lighter order {cloid} does not match venue order ID {venue_order_id}

What it means

During order reconciliation binding, the cached OrderAny for a client_order_id must already carry the same venue order ID that the venue reports. ensure! rejects the call when order.venue_order_id() != Some(venue_order_id), catching an identity mismatch between local cache and venue state.

Source

Thrown at crates/adapters/lighter/src/websocket/dispatch.rs:1301

    /// Restore an exact order identity observed during reconciliation.
    ///
    /// `terminal` reflects the current venue report because the cached order can be stale after a
    /// restart.
    ///
    /// # Errors
    ///
    /// Returns an error when the cached order does not carry the same venue order ID, the client
    /// index is outside the venue-safe range, or the binding conflicts with existing local state.
    pub(crate) fn restore_reconciled_order(
        &self,
        order: &OrderAny,
        client_order_index: i64,
        venue_order_id: VenueOrderId,
        terminal: bool,
    ) -> anyhow::Result<()> {
        let cloid = order.client_order_id();
        anyhow::ensure!(
            order.venue_order_id() == Some(venue_order_id),
            "cached Lighter order {cloid} does not match venue order ID {venue_order_id}",
        );
        anyhow::ensure!(
            (0..=i64::from(CLOID_INDEX_MAX)).contains(&client_order_index),
            "Lighter client_order_index {client_order_index} is outside the venue-safe range",
        );

        if let Some(existing) = self
            .order_identities
            .get(&cloid)
            .map(|entry| entry.value().clone())
        {
            anyhow::ensure!(
                existing.client_order_index == client_order_index
                    && existing.matches_venue_order_id(venue_order_id),
                "active Lighter order {cloid} conflicts with reconciliation binding",
            );

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Clear/rebuild the local order cache and re-reconcile against venue state
  2. Verify the event's client_order_id maps to the correct cached order
  3. Ensure venue_order_id assignment happens before this binding is invoked
Defensive patterns

Strategy: validation

Validate before calling

if order.venue_order_id() != Some(venue_order_id) {
    tracing::warn!("identity mismatch for {cloid}; forcing re-reconcile");
    rebuild_cache_from_venue().await?;
}

Type guard

fn binding_consistent(o: &OrderAny, vid: VenueOrderId) -> bool {
    o.venue_order_id() == Some(vid)
}

Try / catch

if let Err(e) = bind_reconciliation(order, idx, vid, terminal).await {
    tracing::error!("bind failed, re-reconciling: {e}");
    full_reconcile_from_venue().await?;
}

Prevention

When it happens

Trigger: Calling the reconciliation bind helper with an order whose cached venue_order_id is None or differs from the venue_order_id argument — e.g. dispatching a venue event to the wrong cached order, or a stale cache entry.

Common situations: Client order ID collisions after restart, orders restored from cache before venue ID assignment, events from one venue instrument applied to another's cached order.

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