{"record":{"id":"01943322a7da5443","repo":"roboflow/supervision","slug":"video-frame-must-have-shape-self-height-self","errorCode":null,"errorMessage":"Video frame must have shape ({self._height}, {self._width}, 3), got {frame.shape}","messagePattern":"Video frame must have shape \\((.+?), (.+?), 3\\), got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/_cv2/_video.py","lineNumber":234,"sourceCode":"            self._stream = self._container.add_stream(codec, rate=rate)\n            self._stream.width = self._width\n            self._stream.height = self._height\n            self._stream.pix_fmt = pixel_format\n            self._opened = True\n        except Exception as exc:\n            self._error = exc\n            self.release()\n\n    def isOpened(self) -> bool:\n        \"\"\"Return whether the writer initialized successfully.\"\"\"\n        return self._opened\n\n    def write(self, frame: npt.NDArray[np.uint8]) -> None:\n        \"\"\"Encode one BGR frame and mux all packets produced by the encoder.\"\"\"\n        if not self._opened or self._container is None or self._stream is None:\n            raise RuntimeError(\"Video writer is not open\") from self._error\n        if frame.shape != (self._height, self._width, 3):\n            raise ValueError(\n                \"Video frame must have shape \"\n                f\"({self._height}, {self._width}, 3), got {frame.shape}\"\n            )\n        if frame.dtype != np.uint8:\n            raise ValueError(\"Video frames must use uint8 dtype\")\n\n        video_frame = av.VideoFrame.from_ndarray(\n            np.ascontiguousarray(frame), format=\"bgr24\"\n        )\n        for packet in self._stream.encode(video_frame):\n            self._container.mux(packet)\n\n    def release(self) -> None:\n        \"\"\"Flush delayed encoder packets and close the output container.\"\"\"\n        container = self._container\n        stream = self._stream\n        self._container = None\n        self._stream = None","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/_cv2/_video.py#L216-L252","documentation":"The PyAV writer validates every frame against the exact (height, width, 3) shape fixed at construction; av.VideoFrame.from_ndarray requires a matching bgr24 layout. Any frame of different resolution, channel count, or an accidentally transposed (W, H) array is rejected.","triggerScenarios":"Passing frames whose shape differs from the constructor's frame_size — e.g. writer created with (1920, 1080) while frames are 1080p after a resize, width/height swapped at construction, or 2D grayscale frames.","commonSituations":"The classic OpenCV bug of passing (width, height) instead of (height, width) to VideoWriter, annotators that change frame resolution mid-stream, or mixing sources (webcam + file) with one writer.","solutions":["Construct the writer with (height, width) from an actual frame: frame_size=(frame.shape[1], frame.shape[0]) — note OpenCV's VideoWriter takes (width, height).","Resize every frame to the writer's fixed size before write().","Ensure frames are 3-channel BGR; convert grayscale with cv2.cvtColor."],"exampleFix":"# before\nwriter = cv2.VideoWriter('out.mp4', fourcc, fps, (1080, 1920))  # swapped; frames are (1920,1080,3)\n\n# after\nwriter = cv2.VideoWriter('out.mp4', fourcc, fps, (1920, 1080))","handlingStrategy":"validation","validationCode":"h, w = frame.shape[:2]\nwriter = cv2.VideoWriter(path, fourcc, fps, (w, h))  # OpenCV order: (width, height)\nassert frame.shape == (h, w, 3)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive writer frame_size from an actual frame, not from config constants","Remember VideoWriter takes (width, height) while arrays are (height, width, channels)","Resize all frames to one fixed resolution before writing"],"tags":["opencv-fallback","pyav","video-writer","shape-mismatch"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}