roboflow/supervision · error · ValueError

Could not read image from path: {image_path}

Error message

Could not read image from path: {image_path}

What it means

Raised by DetectionDataset._get_image when cv2.imread returns None for a lazy (path-based) dataset. OpenCV returns None — rather than raising — for nonexistent paths, unreadable/corrupt files, unsupported formats, or non-ASCII paths on some platforms, so supervision converts that into an explicit ValueError naming the path.

Source

Thrown at src/supervision/dataset/core.py:155

        # Eliminate duplicates while preserving order
        self.image_paths = list(dict.fromkeys(images))

        self._images_in_memory: dict[str, npt.NDArray[np.uint8]] = {}
        if isinstance(images, dict):
            self._images_in_memory = images
            warn_deprecated(
                "Passing a `Dict[str, np.ndarray]` into `DetectionDataset` is "
                "deprecated in `0.30.0` and will be removed in `0.33.0`. Use "
                "a list of paths `List[str]` instead."
            )

    def _get_image(self, image_path: str) -> npt.NDArray[np.uint8]:
        """Assumes that image is in dataset."""
        if self._images_in_memory:
            return self._images_in_memory[image_path]
        image = cv2.imread(image_path)
        if image is None:
            raise ValueError(f"Could not read image from path: {image_path}")
        return cast(npt.NDArray[np.uint8], image)

    def __len__(self) -> int:
        return len(self._images_in_memory) or len(self.image_paths)

    def __getitem__(self, i: int) -> tuple[str, npt.NDArray[np.uint8], Detections]:
        """
        Returns:
            The image path, image data,
                and its corresponding annotation at index i.
        """
        image_path = self.image_paths[i]
        image = self._get_image(image_path)
        annotation = self.annotations[image_path]
        return image_path, image, annotation

    def __iter__(self) -> Iterator[tuple[str, npt.NDArray[np.uint8], Detections]]:
        """

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Check the path exists and is absolute before dataset construction: Path(p).resolve() on all image_paths.
  2. Run from the directory the paths were built relative to, or normalize with os.path.abspath.
  3. Pre-validate decodability with cv2.imread(p) is not None and drop/repair failing entries.
  4. If files were moved, reconstruct the dataset with updated paths.

Example fix

// before
paths = glob('images/*.jpg')  # relative
ds = DetectionDataset(classes=c, images=paths, annotations=anns)
item = ds[0]  # run from another cwd -> ValueError

// after
from pathlib import Path
paths = [str(Path(p).resolve()) for p in glob('images/*.jpg')]
ds = DetectionDataset(classes=c, images=paths, annotations=anns)
Defensive patterns

Strategy: validation

Validate before calling

bad = [p for p in ds.image_paths if not Path(p).is_file() or cv2.imread(p) is None]
if bad:
    raise FileNotFoundError(f"Unreadable images: {bad}")
item = ds[0]

Try / catch

try:
    _, img, dets = ds[i]
except ValueError as e:
    if "Could not read image" in str(e):
        # re-locate the file or rebuild dataset without it
        raise
    raise

Prevention

When it happens

Trigger: Accessing ds[i] (or iterating) on a path-based DetectionDataset where an image path no longer exists, points outside the dataset root (relative paths resolved from the wrong cwd), or the file is corrupted/not a decodable image.

Common situations: Relative image paths resolved from a different working directory; dataset moved/archived after construction; 0-byte or truncated downloads; EXR/HEIC files OpenCV cannot decode without plugins.

Related errors


AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15). Data as JSON: /api/errors/c0761c17eb73373c. Report an issue: GitHub.