roboflow/supervision · error · OSError

Failed to save image to path: {image_path}

Error message

Failed to save image to path: {image_path}

What it means

Raised by `ImageSink.save_image` when `cv2.imwrite` returns False, meaning OpenCV could not encode/write the image to the constructed path. `cv2.imwrite` signals failure by return value (it does not raise), so supervision converts it to an OSError with the target path. Typical root causes: unwritable directory, missing directory, unsupported/missing file extension, or an image dtype/channels OpenCV cannot encode.

Source

Thrown at src/supervision/utils/image.py:734

        """
        Save image to target directory with optional custom filename.

        Args:
            image: Image to save with shape `(height, width, 3)`
                in BGR format.
            image_name: Custom filename for saved image. If
                `None`, generates name using `image_name_pattern`. Defaults to
                `None`.

        Raises:
            OSError: If `cv2.imwrite` cannot write the image to disk.
        """
        if image_name is None:
            image_name = self.image_name_pattern.format(self.image_count)

        image_path = os.path.join(self.target_dir_path, image_name)
        if not cv2.imwrite(image_path, image):
            raise OSError(f"Failed to save image to path: {image_path}")
        self.image_count += 1

    def __exit__(
        self,
        exc_type: type[BaseException] | None,
        exc_value: BaseException | None,
        exc_traceback: TracebackType | None,
    ) -> None:
        pass


@deprecated(  # type: ignore[untyped-decorator]
    target=TargetMode.NOTIFY,
    deprecated_in="0.27.0",
    remove_in="0.31.0",
)
def create_tiles(
    images: list[ImageType],

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Ensure the target directory exists and is writable: `os.makedirs(path, exist_ok=True)`.
  2. Include a valid extension in `image_name_pattern`, e.g. `'image_{:05d}.png'`.
  3. Convert dtype/channels: `np.ascontiguousarray(image.astype(np.uint8))`, BGR 1- or 3-channel for JPEG.
  4. Check disk space and container volume permissions.

Example fix

# before
with sv.ImageSink(target_dir_path='out', image_name_pattern='frame_{:05d}') as sink:
    sink.save_image(frame)  # no extension -> cv2.imwrite fails
# after
with sv.ImageSink(target_dir_path='out', image_name_pattern='frame_{:05d}.png') as sink:
    sink.save_image(frame)
Defensive patterns

Strategy: try-catch

Validate before calling

os.makedirs(sink.target_dir_path, exist_ok=True)
assert os.access(sink.target_dir_path, os.W_OK), 'target dir not writable'
# ensure uint8 BGR contiguous image
image = np.ascontiguousarray(image.astype(np.uint8))

Try / catch

try:
    sink.save_image(frame)
except OSError as e:
    log.error('failed to write frame: %s', e)
    raise  # or skip frame and continue the video loop

Prevention

When it happens

Trigger: `ImageSink(target_dir_path='out/')` where `out/` does not exist (though the context manager creates it — occurs when saving outside `with`); `image_name_pattern='frame_{:05d}'` producing files with no extension; writing float32 arrays instead of uint8.

Common situations: Running in containers/CI where the mount is read-only; image name patterns that omit '.jpg'; exotic image shapes (odd dims for JPEG, 4-channel PNG mismatch); disk full.

Related errors


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