nautechsystems/nautilus_trader · error
ambiguous Lighter active-order lookup for client_order_index
Error message
ambiguous Lighter active-order lookup for client_order_index {client_order_index} and nonce {nonce} What it means
During reconciliation, the adapter filters the venue's active orders by (client_order_index, nonce) and requires exactly one match. If two or more active orders share the same client_order_index and nonce, the venue state is ambiguous and the lookup is aborted instead of guessing. This protects Nautilus order state from being built from the wrong venue order.
Source
Thrown at crates/adapters/lighter/src/websocket/dispatch.rs:1762
let query = Zeroizing::new(LighterAccountActiveOrdersQuery {
authorization: None,
auth: Some(auth.clone()),
account_index: credential.account_index(),
market_id: market_index,
});
let active = http_client
.get_account_active_orders(&query)
.await
.context("failed to fetch Lighter active orders")?;
let mut matches = active
.orders
.iter()
.filter(|order| order.client_order_index == client_order_index && order.nonce == nonce);
let Some(order) = matches.next() else {
return Ok(None);
};
anyhow::ensure!(
matches.next().is_none(),
"ambiguous Lighter active-order lookup for client_order_index {client_order_index} and nonce {nonce}",
);
let report = parse_http_order_to_report(order, registry, account_id, clock.get_time_ns())
.ok_or_else(|| {
anyhow::anyhow!(
"failed to parse Lighter active order {} for acknowledged create",
order.order_index,
)
})?;
let report = dispatch
.translate_order_cloid(report)
.with_client_order_id(client_order_id);
Ok(Some(dispatch.preserve_pending_order_status(report)))
}
/// Look up a single order via the active and inactive HTTP endpoints, returningView on GitHub (pinned to 18893faf8b)
Solutions
- Fetch the venue open orders and inspect duplicates for that client_order_index; cancel the unwanted duplicate on the venue.
- Ensure the nonce used at submit time is unique per order (check nonce generation logic in the signing/submit path).
- Re-run reconciliation after cancelling duplicates so the lookup resolves to a single order.
Example fix
// before: reconcile by (client_order_index, nonce) with duplicates on venue anyhow::ensure!(matches.next().is_none(), "ambiguous ..."); // after: prevent duplicates upstream by generating a strictly increasing unique nonce per CreateOrder tx
Defensive patterns
Strategy: validation
Validate before calling
let dups: Vec<_> = active.orders.iter().filter(|o| o.client_order_index == idx && o.nonce == nonce).collect();
if dups.len() > 1 { /* cancel duplicates before reconciling */ } Prevention
- Generate a unique nonce per submitted order
- Never reuse client_order_index values
- Inspect venue open orders for duplicates after connection drops
When it happens
Trigger: Calling the active-order lookup/reconciliation path with a client_order_index+nonce pair that matches more than one order in the exchange's open-orders response (e.g. venue allowed a duplicate client_order_index with a colliding nonce).
Common situations: Reconnecting/reconciling after a network split where a submission was retried and the venue recorded two orders with the same client_order_index and nonce; bugs in client-generated nonce handling.
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
- cached Lighter order {cloid} does not match venue order ID {
- active Lighter order {cloid} conflicts with reconciliation b
- retired Lighter order {cloid} conflicts with reconciliation
- retired Lighter binding conflicts at client_order_index {cli
- active Lighter order {cloid} conflicts with venue order ID {
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/73d9ea755d939f15.
Report an issue: GitHub.