nautechsystems/nautilus_trader · error

no Lighter market_index for position report instrument {inst

Error message

no Lighter market_index for position report instrument {instrument_id}

What it means

When a position status report is requested for a specific instrument, the adapter must map the instrument_id to a Lighter market_index via the local registry. If the registry has no market index for that instrument, the mapping (and thus the query) cannot be built and the error is raised. This means the instrument was never registered/loaded into the Lighter instrument registry.

Source

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

            );
            Ok((Vec::new(), false))
        }
    }
}

impl LighterExecutionClient {
    fn cached_position_reports(
        &self,
        cmd: &GeneratePositionStatusReports,
    ) -> anyhow::Result<(Vec<PositionStatusReport>, bool, Option<AHashSet<i16>>)> {
        // Lighter has no REST position source. The latest complete WebSocket
        // snapshot is authoritative, while a skipped row keeps the retained
        // cache available only as explicitly incomplete mass-status data.
        let (mut reports, coverage) = self.dispatch.snapshot_positions_with_coverage();
        let complete = match cmd.instrument_id {
            Some(instrument_id) => {
                let market_id = self.registry.market_index(&instrument_id).ok_or_else(|| {
                    anyhow::anyhow!(
                        "no Lighter market_index for position report instrument {instrument_id}",
                    )
                })?;
                reports.retain(|report| report.instrument_id == instrument_id);
                coverage
                    .as_ref()
                    .is_some_and(|skipped| !skipped.contains(&market_id))
            }
            None => coverage.as_ref().is_some_and(|skipped| skipped.is_empty()),
        };
        Ok((reports, complete, coverage))
    }

    async fn paginate_fill_reports(&self, cmd: &GenerateFillReports) -> anyhow::Result<FillSweep> {
        let Some(credential) = &self.credential else {
            log::warn!("Lighter generate_fill_reports: no credentials");
            return Ok(FillSweep {
                reports: Vec::new(),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the instrument is loaded into the Lighter registry before requesting position reports (add it to the adapter's configured instruments and re-initialize).
  2. Verify the instrument_id is a Lighter instrument and matches the exact venue/symbol format.
  3. Reload or rebuild the registry so market_index mappings are current, then retry.
  4. If the instrument is genuinely unsupported, remove it from the reconciliation scope.

Example fix

// before
let market_id = self.registry.market_index(&instrument_id).ok_or_else(|| {
    anyhow::anyhow!("no Lighter market_index for position report instrument {instrument_id}")
})?;
// after
let market_id = match self.registry.market_index(&instrument_id) {
    Some(idx) => idx,
    None => {
        self.reload_registry_for(&instrument_id).await?;
        self.registry.market_index(&instrument_id).ok_or_else(|| {
            anyhow::anyhow!("no Lighter market_index for position report instrument {instrument_id}")
        })?
    }
};
Defensive patterns

Strategy: validation

Validate before calling

if registry.market_index(&instrument_id).is_none() {
    // register the instrument or drop it from scope before requesting reports
}

Type guard

fn is_lighter_instrument(registry: &Registry, id: &InstrumentId) -> bool { registry.market_index(id).is_some() }

Try / catch

match res {
    Err(e) if e.to_string().contains("no Lighter market_index for position report") => load_instrument_then_retry(id),
    other => other,
}

Prevention

When it happens

Trigger: Calling generate_position_status_reports with cmd.instrument_id = Some(id) where id was not registered by the adapter's instrument loading (e.g. an instrument from a different venue, a stale instrument ID, or subscription/config listing an instrument the adapter never fetched).

Common situations: Reconciliation configured with instruments from another venue or a renamed/migrated instrument ID; requesting reports for an instrument added after the registry was built; typo in instrument ID in config.

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/962a24f6e331c90f. Report an issue: GitHub.