roboflow/supervision · error · RuntimeError
Video writer is not open
Error message
Video writer is not open
What it means
Raised by the PyAV VideoWriter.write() when the writer never opened successfully (or was released). Construction stores any init exception in self._error and defers it; the first write() then raises RuntimeError chained to that root cause — typically an unsupported codec, an unwritable path, or a PyAV/ffmpeg problem.
Source
Thrown at src/supervision/_cv2/_video.py:232
self._container = av.open(str(filename), mode="w")
rate = Fraction(str(fps)).limit_denominator(100_000)
self._stream = self._container.add_stream(codec, rate=rate)
self._stream.width = self._width
self._stream.height = self._height
self._stream.pix_fmt = pixel_format
self._opened = True
except Exception as exc:
self._error = exc
self.release()
def isOpened(self) -> bool:
"""Return whether the writer initialized successfully."""
return self._opened
def write(self, frame: npt.NDArray[np.uint8]) -> None:
"""Encode one BGR frame and mux all packets produced by the encoder."""
if not self._opened or self._container is None or self._stream is None:
raise RuntimeError("Video writer is not open") from self._error
if frame.shape != (self._height, self._width, 3):
raise ValueError(
"Video frame must have shape "
f"({self._height}, {self._width}, 3), got {frame.shape}"
)
if frame.dtype != np.uint8:
raise ValueError("Video frames must use uint8 dtype")
video_frame = av.VideoFrame.from_ndarray(
np.ascontiguousarray(frame), format="bgr24"
)
for packet in self._stream.encode(video_frame):
self._container.mux(packet)
def release(self) -> None:
"""Flush delayed encoder packets and close the output container."""
container = self._container
stream = self._streamView on GitHub (pinned to 7f254d9784)
Solutions
- Check writer.isOpened() immediately after construction and fail fast with your own error if False.
- Inspect the chained exception (__cause__) to find the real init failure — usually fix the codec fourcc or the output path.
- Verify the output directory exists and is writable before creating the writer.
- Do not call write() after release().
Example fix
# before
writer = cv2.VideoWriter('out.mp4', fourcc, fps, (w, h))
writer.write(frame) # RuntimeError: Video writer is not open
# after
writer = cv2.VideoWriter('out.mp4', fourcc, fps, (w, h))
if not writer.isOpened():
raise RuntimeError(f'cannot open out.mp4 with {fourcc}')
writer.write(frame) Defensive patterns
Strategy: validation
Validate before calling
writer = cv2.VideoWriter(path, fourcc, fps, (w, h))
if not writer.isOpened():
raise RuntimeError(f'failed to open video writer for {path}') Try / catch
try:
writer.write(frame)
except RuntimeError as e:
if 'not open' in str(e) and e.__cause__ is not None:
raise RuntimeError(f'writer init failed: {e.__cause__}') from e
raise Prevention
- Always check isOpened() right after construction
- Inspect __cause__ of this RuntimeError to find the real init error
- Verify output directory exists and codec is supported before creating the writer
- Never write after release()
When it happens
Trigger: Calling writer.write(frame) after creating a VideoWriter whose av.open or stream creation failed (bad codec, permission denied, missing directory), or writing after release().
Common situations: Real OpenCV silently absorbs open failures and isOpened() returns False, so code that skips the isOpened() check keeps 'working' (producing empty files); the fallback surfaces the failure at first write instead, surprising ported code.
Related errors
- PyAV video fallback only supports color (3-channel BGR) fram
- Video frame must have shape ({self._height}, {self._width},
- Video frames must use uint8 dtype
- VideoWriter_fourcc requires exactly four characters
- Unsupported video codec: {code}
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/870cf95dcafd5cbf.
Report an issue: GitHub.