nautechsystems/nautilus_trader · error

active Lighter order {cloid} conflicts with reconciliation b

Error message

active Lighter order {cloid} conflicts with reconciliation binding

What it means

When a cached active order exists for the cloid, the reconciliation binding must agree on both client_order_index and venue order ID. If the new binding disagrees with the stored OrderIdentity, ensure! fails — a conflicting identity would otherwise silently corrupt the order map.

Source

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

        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",
            );

            if terminal {
                self.retire_order_identity(&cloid);
            } else if order.is_triggered() == Some(true) {
                self.mark_triggered_emitted(cloid);
            }
            return Ok(());
        }

        if let Some(existing) = self.retired_orders.identity_for_cloid(&cloid) {
            anyhow::ensure!(
                terminal
                    && existing.client_order_index == client_order_index
                    && existing.matches_venue_order_id(venue_order_id),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the conflicting OrderIdentity vs the event values in the message context
  2. Purge the conflicting cloid from order_identities and re-reconcile from venue state
  3. Guarantee unique client_order_ids per session
Defensive patterns

Strategy: validation

Validate before calling

if let Some(existing) = state.identity_for(&cloid) {
    if existing.client_order_index != idx || !existing.matches_venue_order_id(vid) {
        tracing::error!("conflict for {cloid}; rebuilding state");
        full_reconcile_from_venue().await?;
    }
}

Try / catch

if let Err(e) = bind_reconciliation(order, idx, vid, terminal).await {
    if e.to_string().contains("conflicts with reconciliation binding") {
        purge_cloid(&cloid);
        full_reconcile_from_venue().await?;
        return Ok(());
    }
    return Err(e);
}

Prevention

When it happens

Trigger: Rebinding an active order whose stored client_order_index or venue_order_id differs from the values in the current reconciliation event (e.g. duplicate cloid, wrong event routed, or cache poisoned by an earlier bad bind).

Common situations: Two orders sharing a client_order_id, stale in-memory state after reconnect, replayed events from a previous session.

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