nautechsystems/nautilus_trader · error

Lighter client_order_index

Error message

Lighter client_order_index {client_order_index} is outside the venue-safe range

What it means

The venue only accepts client_order_index values in [0, CLOID_INDEX_MAX]; this ensure! rejects any reconciliation bind where the index from the venue event falls outside that range, protecting against malformed or hostile venue payloads.

Solutions

  1. Log the offending event payload and check the venue API schema version
  2. Validate/clamp client_order_index at the parse boundary before dispatch
  3. Update the adapter if Lighter widened or changed the index range
Defensive patterns

Strategy: validation

Validate before calling

if !(0..=i64::from(CLOID_INDEX_MAX)).contains(&client_order_index) {
    tracing::error!("dropping malformed event, client_order_index={client_order_index}");
    return Ok(());
}

Type guard

fn valid_cloid_index(i: i64) -> bool { (0..=i64::from(CLOID_INDEX_MAX)).contains(&i) }

Try / catch

if let Err(e) = bind_reconciliation(order, idx, vid, terminal).await {
    if e.to_string().contains("outside the venue-safe range") {
        tracing::error!("malformed venue payload: {e}; skipping event");
        return Ok(());
    }
    return Err(e);
}

Prevention

When it happens

Trigger: A venue order-status event carries a client_order_index that is negative or exceeds CLOID_INDEX_MAX while reconciling/binding an order.

Common situations: Unexpected venue API payload shape changes, i64 overflow of a parsed field, decoding bug producing garbage indices.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/4c6750e0f86202b6. Report an issue: GitHub.

Appendix: source

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

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

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

View on GitHub (pinned to 18893faf8b)