nautechsystems/nautilus_trader · error

active Lighter order {cloid} conflicts with venue order ID {

Error message

active Lighter order {cloid} conflicts with venue order ID {venue_order_id}

What it means

For a new non-terminal bind, the venue_id_map must not already associate the cloid with a different venue order ID. ensure! fails when the cached venue ID for this cloid differs from the event's venue_order_id, preventing one client order from being silently rebound to another venue order.

Source

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

                    && existing.matches_venue_order_id(venue_order_id),
                "retired Lighter order {cloid} conflicts with reconciliation binding",
            );
            return Ok(());
        }

        let identity = OrderIdentity::restored(order, client_order_index, venue_order_id);

        if terminal {
            anyhow::ensure!(
                self.retired_orders
                    .cloid_for_venue(client_order_index, venue_order_id)
                    .is_none(),
                "retired Lighter binding conflicts at client_order_index {client_order_index} and venue order ID {venue_order_id}",
            );
            self.retired_orders.insert(cloid, identity);
        } else {
            if let Some(existing) = self.venue_id_map.get(&cloid) {
                anyhow::ensure!(
                    *existing.value() == venue_order_id,
                    "active Lighter order {cloid} conflicts with venue order ID {venue_order_id}",
                );
            }

            match self.cloid_map.entry(client_order_index) {
                dashmap::mapref::entry::Entry::Vacant(entry) => {
                    self.venue_id_map.insert(cloid, venue_order_id);
                    self.order_identities.insert(cloid, identity);
                    entry.insert(cloid);
                    if order.is_triggered() == Some(true) {
                        self.mark_triggered_emitted(cloid);
                    }
                }
                dashmap::mapref::entry::Entry::Occupied(_) => {
                    anyhow::bail!(
                        "active Lighter binding conflicts at client_order_index {client_order_index}",
                    );

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Reset the adapter's order state (venue_id_map/cloid_map) and re-reconcile
  2. Use unique client order IDs per session
  3. Trace where the cloid was first bound and why the venue ID changed
Defensive patterns

Strategy: validation

Validate before calling

if let Some(existing) = state.venue_id_for(&cloid) {
    if *existing != vid {
        tracing::error!("cloid {cloid} remapped {} -> {vid}; rebuilding", existing);
        reset_order_state().await?;
    }
}

Try / catch

if let Err(e) = bind_reconciliation(order, idx, vid, terminal).await {
    if e.to_string().contains("conflicts with venue order ID") {
        reset_order_state().await?;
        full_reconcile_from_venue().await?;
        return Ok(());
    }
    return Err(e);
}

Prevention

When it happens

Trigger: An active-order event remaps an existing cloid to a new venue_order_id (wrong event routing, cloid reuse, or corrupted venue_id_map).

Common situations: Reusing client_order_ids across sessions without clearing state, misrouted dispatch after reconnect, venue data anomalies.

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