{"record":{"id":"f20533a7b403e0d8","repo":"nautechsystems/nautilus_trader","slug":"lighter-position-snapshot-does-not-cover-the-reque","errorCode":null,"errorMessage":"Lighter position snapshot does not cover the requested instrument scope","messagePattern":"Lighter position snapshot does not cover the requested instrument scope","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/execution.rs","lineNumber":4873,"sourceCode":"        Self::log_report_receipt(reports.len(), \"OrderStatusReport\", cmd.log_receipt_level);\n        Ok(reports)\n    }\n\n    async fn generate_fill_reports(\n        &self,\n        cmd: GenerateFillReports,\n    ) -> anyhow::Result<Vec<FillReport>> {\n        let reports = self.paginate_fill_reports(&cmd).await?.reports;\n        Self::log_report_receipt(reports.len(), \"FillReport\", cmd.log_receipt_level);\n        Ok(reports)\n    }\n\n    async fn generate_position_status_reports(\n        &self,\n        cmd: &GeneratePositionStatusReports,\n    ) -> anyhow::Result<Vec<PositionStatusReport>> {\n        let (reports, complete, _) = self.cached_position_reports(cmd)?;\n        anyhow::ensure!(\n            complete,\n            \"Lighter position snapshot does not cover the requested instrument scope\",\n        );\n        Self::log_report_receipt(reports.len(), \"PositionStatusReport\", cmd.log_receipt_level);\n        Ok(reports)\n    }\n\n    async fn generate_mass_status(\n        &self,\n        lookback_mins: Option<u64>,\n    ) -> anyhow::Result<Option<ExecutionMassStatus>> {\n        let ts_init = self.clock.get_time_ns();\n\n        // Scope inactive orders at the venue and stop descending trade\n        // pagination once it crosses this local lookback boundary.\n        let lookback_start = lookback_mins\n            .map(DurationNanos::try_from_mins)\n            .transpose()?","sourceCodeStart":4855,"sourceCodeEnd":4891,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/execution.rs#L4855-L4891","documentation":"generate_position_status_reports builds position reports from a cached Lighter snapshot and a completeness flag. When the snapshot only covered part of the requested instrument scope (complete == false), the method refuses to return partial data presented as a full reconciliation and fails with this ensure!. It protects reconciliation from treating an incomplete exchange snapshot as authoritative.","triggerScenarios":"Calling generate_position_status_reports (mass status / reconciliation) when the cached position snapshot was marked incomplete — e.g. a paginated or partial Lighter position fetch that did not cover every instrument in scope, or a previous per-instrument query that skipped rows so the retained cache is only explicitly incomplete mass-status data.","commonSituations":"Lighter API returning partial position pages during reconnect, snapshots taken while instruments are still being registered in the registry, or reconciliation running immediately after startup before a full position snapshot has been cached.","solutions":["Retry generate_position_status_reports after the Lighter position snapshot refreshes to full coverage.","Check which instruments were skipped in the snapshot fetch (logs around snapshot_positions_with_coverage) and ensure those markets are registered in the registry.","If a specific instrument is intended, call the per-instrument path (cmd.instrument_id set) instead of requesting the full scope.","Verify network/API stability to Lighter; partial snapshots are usually caused by failed or truncated pages."],"exampleFix":"// before\nlet (reports, complete, _) = self.cached_position_reports(cmd)?;\nanyhow::ensure!(complete, \"Lighter position snapshot does not cover the requested instrument scope\");\n// after\nlet (reports, complete, _) = self.cached_position_reports(cmd)?;\nif !complete {\n    // wait for a fresh full snapshot instead of failing immediately\n    self.refresh_position_snapshot().await?;\n    let (reports, complete, _) = self.cached_position_reports(cmd)?;\n    anyhow::ensure!(complete, \"Lighter position snapshot does not cover the requested instrument scope\");\n    return Ok(reports);\n}","handlingStrategy":"retry","validationCode":"let (reports, complete, _) = cached_position_reports(cmd)?;\nif !complete { /* defer or retry */ }","typeGuard":"fn snapshot_is_complete(coverage: &Option<Coverage>) -> bool { coverage.as_ref().map(|c| c.is_complete()).unwrap_or(false) }","tryCatchPattern":"match client.generate_position_status_reports(cmd).await {\n    Ok(reports) => process(reports),\n    Err(e) if e.to_string().contains(\"does not cover the requested instrument scope\") => schedule_retry(e),\n    Err(e) => return Err(e),\n}","preventionTips":["Wait for a confirmed full snapshot before triggering reconciliation","Ensure all in-scope instruments are registered before mass status","Monitor Lighter API completeness signals in logs"],"tags":["reconciliation","position-reports","lighter","snapshot-coverage"],"backgroundTag":"incomplete-snapshot","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}