nautechsystems/nautilus_trader · error
active Lighter binding conflicts at client_order_index {clie
Error message
active Lighter binding conflicts at client_order_index {client_order_index} What it means
Raised when binding a cloid to a client_order_index finds the index already occupied by a different cloid in the active-bindings map (dashmap Entry::Occupied). The dispatcher enforces a one-to-one mapping between client_order_index and cloid for active orders; a collision means duplicate or inconsistent order identity state.
Source
Thrown at crates/adapters/lighter/src/websocket/dispatch.rs:1367
} 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}",
);
}
}
}
Ok(())
}
/// Drop a cloid registration (called from the spawn's error branch when
/// the tx never reaches the wire).
pub(crate) fn forget_cloid(&self, index: i64) {
self.cloid_map.remove(&index);
}
/// Resolve a venue client-order index across active and replay caches.
pub(crate) fn resolve_client_order_index(&self, index: i64) -> Option<ClientOrderId> {
self.cloid_map
.get(&index)View on GitHub (pinned to 18893faf8b)
Solutions
- Generate a fresh unique cloid/client_order_index for the retried order instead of reusing the old identity.
- Ensure a single owner (one execution client) assigns client_order_index values for the account.
- Clear or rebuild the binding map from a fresh reconciliation snapshot if it contains stale entries.
- Serialize order submissions (or guard the binding step) so concurrent tasks cannot claim the same index.
- Check for counter resets after restarts; persist or re-derive the next index from exchange state.
Example fix
// before: reusing the same index on retry submit_order(order.with_client_order_index(prev_index)).await?; // -> active Lighter binding conflicts at client_order_index 42 // after: allocate a new index per submission let idx = next_unique_client_order_index(); submit_order(order.with_client_order_index(idx)).await?;
Defensive patterns
Strategy: validation
Validate before calling
// before submitting, allocate a guaranteed-unique index let idx = next_unique_client_order_index(); // atomic counter per account
Try / catch
match submit_order(order).await {
Err(e) if e.to_string().contains("binding conflicts") => {
log::error!("duplicate order identity: {e:#}");
// regenerate cloid + index and resubmit once
let order = order.with_new_identity();
submit_order(order).await?;
}
r => r?,
} Prevention
- Never reuse client_order_index/cloid on retries — allocate fresh ones
- Use a single atomic counter or coordinator for index assignment
- Serialize order submissions across strategy instances
- Rebuild bindings from exchange reconciliation after reconnects
When it happens
Trigger: Restoring/registering an order whose client_order_index is already bound to another cloid — e.g. two orders generated with the same index, a reconciliation replay re-inserting an existing binding, or concurrent submissions racing to claim the same index.
Common situations: Running multiple strategy instances that derive indices from a shared counter without coordination; re-sending an order after a timeout without generating a fresh cloid; a reconnect/reconcile path replaying bindings that are already present; clock/counter reset causing index reuse.
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
- Lighter client_order_index probe exhausted after {} attempts
- {FAILED}: {e}
- {FAILED}: {e}
- {FAILED}: {e}
- {FAILED}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/7deda50f55f6de1f.
Report an issue: GitHub.