commaai/openpilot · error · RuntimeError

No valid camera paths

Error message

No valid camera paths

What it means

FrameQueue.__init__ probes the first non-empty entry of camera_paths to learn frame dimensions before starting its worker thread. If every entry is None/empty, there is nothing to probe and it raises. This is an upfront guard: the clip generator cannot even determine frame size, so no frames can be produced.

Source

Thrown at openpilot/tools/clip/run.py:175

          result = subprocess.run(["ffmpeg", "-v", "quiet", "-i", "-", "-f", "rawvideo", "-pix_fmt", "nv12", "-"],
                                  input=f.read(), capture_output=True)
        if result.returncode != 0:
          raise RuntimeError(f"ffmpeg failed: {result.stderr.decode()}")
        seg_frames = np.frombuffer(result.stdout, dtype=np.uint8).reshape(-1, w * h * 3 // 2)
        get_frame = seg_frames.__getitem__
      else:
        get_frame = FrameReader(path, pix_fmt="nv12").get

    assert get_frame is not None
    yield global_idx, get_frame(local_idx)


class FrameQueue:
  def __init__(self, camera_paths, start_time, end_time, fps=20, prefetch_count=60, use_qcam=False):
    # Probe first valid camera file for dimensions
    first_path = next((p for p in camera_paths if p), None)
    if not first_path:
      raise RuntimeError("No valid camera paths")
    self.frame_w, self.frame_h = get_frame_dimensions(first_path)

    self._queue, self._stop, self._error = queue.Queue(maxsize=prefetch_count), threading.Event(), None
    self._thread = threading.Thread(target=self._worker,
                                    args=(camera_paths, start_time, end_time, fps, use_qcam, (self.frame_w, self.frame_h)), daemon=True)
    self._thread.start()

  def _worker(self, camera_paths, start_time, end_time, fps, use_qcam, frame_size):
    try:
      for idx, data in iter_segment_frames(camera_paths, start_time, end_time, fps, use_qcam, frame_size):
        if self._stop.is_set():
          break
        self._queue.put((idx, data.tobytes()))
    except Exception as e:
      logger.exception("Decode error")
      self._error = e
    finally:
      self._queue.put(None)

View on GitHub (pinned to 516ec1e682)

Solutions

  1. Verify the route has camera files: list the segments and check qcamera.ts/camera files exist on disk or remotely
  2. Fix route resolution upstream - print camera_paths before constructing FrameQueue and ensure at least one real path
  3. If using remote routes, make sure the tooling has downloaded/linked camera files first

Example fix

# before
FrameQueue([None, None], 0, 10)

# after
paths = [p for p in camera_paths if p]
assert paths, "no camera files resolved for this route"
FrameQueue(camera_paths, 0, 10)
Defensive patterns

Strategy: validation

Validate before calling

valid = [p for p in camera_paths if p]
assert valid, 'camera_paths has no usable entries - resolve the route first'
import os
assert any(os.path.isfile(p) for p in valid), 'no camera files exist on disk'

Type guard

def has_valid_camera_paths(camera_paths: list) -> bool:
    """True when at least one camera path is a non-empty string."""
    return any(isinstance(p, str) and p for p in camera_paths)

Prevention

When it happens

Trigger: Constructing FrameQueue with a camera_paths list containing only None or '' (route with no camera segments located); passing an empty list; route resolution logic upstream returned placeholders for missing files.

Common situations: Route name typo so segment lookup found nothing; fully un-uploaded route (only logs, no cameras); passing directory names instead of file paths.

Related errors


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