nautechsystems/nautilus_trader · error

no Lighter market_index for instrument {instrument_id}

Error message

no Lighter market_index for instrument {instrument_id}

What it means

Before querying account active orders, the handler resolves the instrument_id to a Lighter market_index via the local registry. If the registry has no entry, it returns this error — the adapter cannot query per-market without the numeric market index.

Source

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

#[expect(
    clippy::too_many_arguments,
    reason = "exact create identity and report context cross the REST translation boundary"
)]
pub(crate) async fn lookup_create_order_status_report(
    http_client: &LighterHttpClient,
    registry: &Arc<MarketRegistry>,
    credential: &Credential,
    account_id: AccountId,
    instrument_id: InstrumentId,
    client_order_id: ClientOrderId,
    client_order_index: i64,
    nonce: i64,
    dispatch: &WsDispatchState,
    clock: &'static AtomicTime,
) -> anyhow::Result<Option<OrderStatusReport>> {
    let market_index = registry
        .market_index(&instrument_id)
        .ok_or_else(|| anyhow::anyhow!("no Lighter market_index for instrument {instrument_id}"))?;
    let auth = mint_auth_token(credential)?;
    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);

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the instrument_id exactly matches one loaded into the adapter's registry
  2. Reload/refresh the instrument registry and retry
  3. Confirm the instrument exists on Lighter and the adapter was configured for it
Defensive patterns

Strategy: try-catch

Validate before calling

let market_index = registry.market_index(&instrument_id);
if market_index.is_none() {
    return Err(anyhow!("instrument {instrument_id} not registered; load instruments first"));
}

Type guard

fn registered(reg: &Registry, id: InstrumentId) -> Option<i64> { reg.market_index(&id) }

Try / catch

match build_order_status_report(instrument_id, ...).await {
    Ok(r) => r,
    Err(e) if e.to_string().contains("no Lighter market_index") => {
        reload_instrument_registry().await?;
        retry_report().await;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Requesting order status reports for an instrument_id that was never registered/loaded into the instrument registry (e.g. wrong instrument_id string, universe not initialized, or instrument added on venue after adapter startup).

Common situations: Typo'd or wrong-venue instrument IDs, subscribing before instruments were loaded, new market listed after adapter start.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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