nautechsystems/nautilus_trader · error

no Lighter market_index registered for instrument {}

Error message

no Lighter market_index registered for instrument {}

What it means

prepare_cancel_order_plan could not resolve the CancelOrder command's instrument_id to a Lighter market_index in the registry. Cancels are sent per Lighter market index, so without that mapping the cancel cannot be signed.

Source

Thrown at crates/adapters/lighter/src/execution.rs:1780

                .send_cancel_order(prepared, emit_cancel_rejected)
                .await;
            Ok(())
        });
    }

    fn can_emit_order_cancel_rejected(&self, client_order_id: &ClientOrderId) -> bool {
        self.core
            .cache()
            .order(client_order_id)
            .is_none_or(|order| order.is_pending_cancel())
    }

    fn prepare_cancel_order_plan(&self, cmd: &CancelOrder) -> anyhow::Result<CancelOrderPlan> {
        let market_index = self
            .registry
            .market_index(&cmd.instrument_id)
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "no Lighter market_index registered for instrument {}",
                    cmd.instrument_id,
                )
            })?;

        self.core.cache().try_order(&cmd.client_order_id)?;

        // Lighter cancel_order targets a single order by venue order_id.
        // The map is populated on the first OrderStatusReport for the cloid.
        let voi = cmd
            .venue_order_id
            .or_else(|| self.dispatch.lookup_venue_order_id(&cmd.client_order_id))
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "cannot cancel Lighter order {}: venue order_id not yet known \
                     (await OrderAccepted before issuing cancel)",
                    cmd.client_order_id,
                )

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the instrument_id matches a registered Lighter instrument and fix the symbol/venue.
  2. Confirm instruments were loaded/registered at startup before any cancel is issued.
  3. Filter the strategy's cancel logic to only instruments present in the registry.
  4. Check startup logs for instrument load failures.

Example fix

// before
let cmd = CancelOrder::new(instrument_id_unknown, client_order_id, None);
// after
if registry.market_index(&instrument_id_unknown).is_some() {
    let cmd = CancelOrder::new(instrument_id_unknown, client_order_id, None);
    execution.cancel_order(cmd)?;
}
Defensive patterns

Strategy: validation

Validate before calling

// Rust
if registry.market_index(&cmd.instrument_id).is_none() {
    log::warn!("skipping cancel for unregistered instrument {}", cmd.instrument_id);
    return Ok(());
}

Try / catch

match adapter.cancel_order(cmd) {
    Err(e) if e.to_string().contains("no Lighter market_index registered") => {
        log::error!("cancel for unknown instrument {}", cmd.instrument_id);
        Ok(()) // or surface, depending on policy
    }
    other => other,
}

Prevention

When it happens

Trigger: dispatch_signed_cancel_order or batch_cancel_orders with a CancelOrder for an instrument never registered with the adapter (unknown symbol, wrong venue, instruments not loaded).

Common situations: Canceling orders after switching configuration to different markets; strategy holding stale instrument_ids from a previous session; instrument registration failed at startup; canceling cross-venue by mistake.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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