roboflow/supervision · error · RuntimeError

Could not open video writer for {self.target_path}

Error message

Could not open video writer for {self.target_path}

What it means

Raised by VideoSink.__enter__ (via its writer setup) in supervision.utils.video when cv2.VideoWriter constructs but fails to actually open the target path (isOpened() is False). OpenCV regularly returns a writer object for impossible targets — bad directory, unwritable location, or an unsupported FOURCC/container combination — so supervision checks isOpened() and raises RuntimeError after releasing the dead writer.

Source

Thrown at src/supervision/utils/video.py:142

        fourcc_fn = cast(
            Callable[[str, str, str, str], int], getattr(cv2, "VideoWriter_fourcc")
        )
        try:
            self.__fourcc = int(fourcc_fn(*self.__codec))
        except TypeError as e:
            logger.warning("%s. Defaulting to mp4v...", str(e))
            self.__fourcc = int(fourcc_fn(*"mp4v"))
        self.__writer = cv2.VideoWriter(
            self.target_path,
            self.__fourcc,
            self.video_info.fps,
            self.video_info.resolution_wh,
        )
        # OpenCV can construct a writer object that is not usable for the target path.
        if not self.__writer.isOpened():
            self.__writer.release()
            self.__writer = None
            raise RuntimeError(f"Could not open video writer for {self.target_path}")
        return self

    def write_frame(self, frame: npt.NDArray[np.uint8]) -> None:
        """
        Writes a single video frame to the target video file.

        Args:
            frame: The video frame to be written to the file. The frame
                must be in BGR color format.
        """
        # Preserve the context-manager invariant instead of silently dropping frames.
        if self.__writer is None:
            raise RuntimeError("write_frame requires an open VideoSink context.")
        self.__writer.write(frame)

    def __exit__(
        self,
        exc_type: type[BaseException] | None,

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Create the parent directory first: os.makedirs(os.path.dirname(target_path) or '.', exist_ok=True).
  2. Fall back to a widely available codec: VideoSink(..., video_codec='mp4v') with a .mp4 name.
  3. Check write permission on the target directory (os.access(dir, os.W_OK)).
  4. Verify with a minimal cv2.VideoWriter test if a custom FOURCC is required.

Example fix

// before
with sv.VideoSink('output/out.mp4', info) as sink:  # output/ missing

// after
os.makedirs('output', exist_ok=True)
with sv.VideoSink('output/out.mp4', info) as sink:
    ...
Defensive patterns

Strategy: validation

Validate before calling

target_dir = os.path.dirname(os.path.abspath(target_path))
os.makedirs(target_dir, exist_ok=True)
if not os.access(target_dir, os.W_OK):
    raise PermissionError(target_dir)
with sv.VideoSink(target_path, info, video_codec='mp4v') as sink:
    ...

Try / catch

try:
    sink_ctx = sv.VideoSink(target_path, info)
    sink_ctx.__enter__()
except RuntimeError as e:
    if 'Could not open video writer' in str(e):
        sink_ctx = sv.VideoSink(fallback_path, info, video_codec='mp4v')
        sink_ctx.__enter__()
    else:
        raise

Prevention

When it happens

Trigger: with sv.VideoSink('out/x.mp4', video_info) as sink: when out/ does not exist; using codec='x264' without the codec available locally; writing .avi with an mp4-oriented FOURCC; target on read-only storage.

Common situations: Output directories never created (mkdir -p forgotten); codec string from a tutorial that the local OpenCV build cannot encode; permission-restricted mount or container filesystem; extension/FOURCC mismatch like video_codec='mp4v' with a .avi name.

Related errors


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