{"record":{"id":"192ff3e58965dd56","repo":"commaai/openpilot","slug":"did-not-find-fn-for-seg-idxs-needed-seg-idxs-o","errorCode":null,"errorMessage":"Did not find {fn} for seg idxs {needed_seg_idxs} of {sr.route_name}","messagePattern":"Did not find (.+?) for seg idxs (.+?) of (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"openpilot/tools/lib/logreader.py","lineNumber":184,"sourceCode":"  # Build a dict of valid files as we evaluate each source. May contain mix of rlogs, qlogs, and None.\n  # This function only returns when we've sourced all files, or throws an exception\n  valid_files: dict[int, str] = {}\n  for fn in try_fns:\n    for source in sources:\n      try:\n        files = source(sr, needed_seg_idxs, fn)\n\n        # Build a dict of valid files\n        valid_files |= files\n\n        # Don't check for segment files that have already been found\n        needed_seg_idxs = [idx for idx in needed_seg_idxs if idx not in valid_files]\n\n        # We've found all files, return them\n        if len(needed_seg_idxs) == 0:\n          return list(valid_files.values())\n        else:\n          raise FileNotFoundError(f\"Did not find {fn} for seg idxs {needed_seg_idxs} of {sr.route_name}\")\n\n      except Exception as e:\n        exceptions[source.__name__] = e\n\n    if fn == try_fns[0]:\n      missing_logs = len(needed_seg_idxs)\n      if mode == ReadMode.AUTO:\n        cloudlog.warning(f\"{missing_logs}/{len(sr.seg_idxs)} rlogs were not found, falling back to qlogs for those segments...\")\n      elif mode == ReadMode.AUTO_INTERACTIVE:\n        if input(f\"{missing_logs}/{len(sr.seg_idxs)} rlogs were not found, would you like to fallback to qlogs for those segments? (y/N) \").lower() != \"y\":\n          break\n\n  missing_logs = len(needed_seg_idxs)\n  raise LogsUnavailable(f\"{missing_logs}/{len(sr.seg_idxs)} logs were not found, please ensure all logs \" +\n                        \"are uploaded. You can fall back to qlogs with '/a' selector at the end of the route name.\\n\\n\" +\n                        \"Exceptions for sources:\\n  - \" + \"\\n  - \".join([f\"{k}: {repr(v)}\" for k, v in exceptions.items()]))\n\n","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/commaai/openpilot/blob/516ec1e68203439a73f340f1d0b3b91eabc626ee/openpilot/tools/lib/logreader.py#L166-L202","documentation":"In RouteFrameReader/LogReader's multi-segment resolution, after querying all internal file sources for the needed segment indices, any still-missing indices raise FileNotFoundError listing them. This inner raise is normally caught per-source and aggregated; seeing it directly means a source threw it outside the usual fallback flow (or you called the internal helper).","triggerScenarios":"Requesting a SegmentRange like 'route/0--5' when some segments' rlogs are not on the device, the local data dir, or the API; using a source list that lacks the location holding those segments.","commonSituations":"Segments not yet uploaded from the device; misconfigured OPENPILOT_LOGS/data dir; route partially purged from the backend; reading qlog-only routes with rlog selector.","solutions":["Let the standard fallback run: append '/a' to the route/range string to fall back to qlogs automatically","Verify the segments exist: check the route files via the API or your data directory listing","Narrow the range to only existing segments (e.g. route/0--3 instead of 0--9)"],"exampleFix":"# before\nlogs = LogReader('b0c9d232...|2022-01-01--00-00-00/0--9')\n\n# after\nlogs = LogReader('b0c9d232...|2022-01-01--00-00-00/0--9/a')  # fall back to qlogs for missing segments","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    logs = LogReader(route_or_range)\nexcept FileNotFoundError:\n    logs = LogReader(route_or_range + '/a')  # qlog fallback","preventionTips":["Append '/a' when rlog completeness is uncertain","Check which segments exist before requesting a wide range","Ensure segments are uploaded before running offline tools"],"tags":["logs","segments","logreader","missing-files"],"backgroundTag":null,"analyzedSha":"516ec1e68203439a73f340f1d0b3b91eabc626ee","analyzedAt":"2026-08-15T00:17:37.461Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}