commaai/openpilot · error · FileNotFoundError

Did not find {fn} for seg idxs {needed_seg_idxs} of {sr.rout

Error message

Did not find {fn} for seg idxs {needed_seg_idxs} of {sr.route_name}

What it means

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).

Source

Thrown at openpilot/tools/lib/logreader.py:184

  # Build a dict of valid files as we evaluate each source. May contain mix of rlogs, qlogs, and None.
  # This function only returns when we've sourced all files, or throws an exception
  valid_files: dict[int, str] = {}
  for fn in try_fns:
    for source in sources:
      try:
        files = source(sr, needed_seg_idxs, fn)

        # Build a dict of valid files
        valid_files |= files

        # Don't check for segment files that have already been found
        needed_seg_idxs = [idx for idx in needed_seg_idxs if idx not in valid_files]

        # We've found all files, return them
        if len(needed_seg_idxs) == 0:
          return list(valid_files.values())
        else:
          raise FileNotFoundError(f"Did not find {fn} for seg idxs {needed_seg_idxs} of {sr.route_name}")

      except Exception as e:
        exceptions[source.__name__] = e

    if fn == try_fns[0]:
      missing_logs = len(needed_seg_idxs)
      if mode == ReadMode.AUTO:
        cloudlog.warning(f"{missing_logs}/{len(sr.seg_idxs)} rlogs were not found, falling back to qlogs for those segments...")
      elif mode == ReadMode.AUTO_INTERACTIVE:
        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":
          break

  missing_logs = len(needed_seg_idxs)
  raise LogsUnavailable(f"{missing_logs}/{len(sr.seg_idxs)} logs were not found, please ensure all logs " +
                        "are uploaded. You can fall back to qlogs with '/a' selector at the end of the route name.\n\n" +
                        "Exceptions for sources:\n  - " + "\n  - ".join([f"{k}: {repr(v)}" for k, v in exceptions.items()]))

View on GitHub (pinned to 516ec1e682)

Solutions

  1. Let the standard fallback run: append '/a' to the route/range string to fall back to qlogs automatically
  2. Verify the segments exist: check the route files via the API or your data directory listing
  3. Narrow the range to only existing segments (e.g. route/0--3 instead of 0--9)

Example fix

# before
logs = LogReader('b0c9d232...|2022-01-01--00-00-00/0--9')

# after
logs = LogReader('b0c9d232...|2022-01-01--00-00-00/0--9/a')  # fall back to qlogs for missing segments
Defensive patterns

Strategy: fallback

Try / catch

try:
    logs = LogReader(route_or_range)
except FileNotFoundError:
    logs = LogReader(route_or_range + '/a')  # qlog fallback

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15). Data as JSON: /api/errors/192ff3e58965dd56. Report an issue: GitHub.