{"record":{"id":"148c77bfb90ce908","repo":"invoke-ai/InvokeAI","slug":"no-frames-decoded-from-video-path","errorCode":null,"errorMessage":"No frames decoded from {video_path}","messagePattern":"No frames decoded from (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/app/util/video_decode_worker.py","lineNumber":255,"sourceCode":"        return\n\n    import cv2\n\n    capture = cv2.VideoCapture(str(video_path))\n    if not capture.isOpened():\n        capture.release()\n        raise FileNotFoundError(f\"Unable to open video at {video_path}\")\n    try:\n        while True:\n            ok, frame_bgr = capture.read()\n            if not ok or frame_bgr is None:\n                break\n            _emit_stream_frame(cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGB))\n            emitted = True\n    finally:\n        capture.release()\n    if not emitted:\n        raise ValueError(f\"No frames decoded from {video_path}\")\n\n\ndef main(argv: list[str]) -> int:\n    try:\n        _limit_worker_memory()\n        command = argv[1]\n        if command == \"stream\":\n            _assert_decodable_dims(Path(argv[2]))\n            _stream(Path(argv[2]))\n        elif command == \"probe\":\n            width, height, duration, fps, codec = _probe(Path(argv[2]))\n            print(json.dumps({\"width\": width, \"height\": height, \"duration\": duration, \"fps\": fps, \"codec\": codec}))\n        elif command == \"frame\":\n            _assert_decodable_dims(Path(argv[2]))\n            image = _extract_frame(Path(argv[2]), int(argv[3]))\n            if image is None:\n                print(\"no frame decoded\", file=sys.stderr)\n                return 1","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/util/video_decode_worker.py#L237-L273","documentation":"Raised by the video decode worker subprocess when OpenCV (cv2.VideoCapture) opened the file but returned zero decodable frames for the whole stream. It signals that the container exists and opens, but no image data could be produced — typically a codec issue or an empty/corrupt stream. The worker emits this instead of silently returning an empty frame list so the parent knows decoding truly failed.","triggerScenarios":"Calling _stream/main on a video whose codec OpenCV's FFmpeg backend cannot decode (e.g. exotic codecs like ProRes, AV1 without support), a truncated/corrupt file, an audio-only file, or a path pointing to an empty file. Also occurs if cv2.cvtColor receives frames but the capture immediately hits EOF due to a damaged container index.","commonSituations":"Users upload videos recorded with device-specific codecs not in the installed OpenCV's FFmpeg build; headless Docker images missing opencv-python full video support (opencv-python-headless without FFmpeg libs); zero-byte or interrupted uploads; testing with a text file renamed to .mp4.","solutions":["Verify the file with ffprobe: if ffprobe shows no video stream or a codec your OpenCV build lacks, transcode first (ffmpeg -i in.mp4 -c:v libx264 -pix_fmt yuv420p out.mp4).","Ensure the OpenCV build has FFmpeg support: check cv2.getBuildInformation() for 'FFMPEG: YES'; reinstall opencv-python (not headless) if missing.","Validate the upload before decoding: reject zero-byte files and files with no video stream (e.g. probe with video_thumbnails.probe_video first).","If the file is simply corrupt from a failed upload, ask the user to re-upload."],"exampleFix":"// before\nframes = list(iter_video_frames(path))  # ValueError: No frames decoded from path\n// after\ninfo = probe_video(path, timeout=30)\nif info is None or info.width == 0:\n    raise HTTPException(415, f\"Unsupported or corrupt video: {path}\")\nframes = list(iter_video_frames(path))","handlingStrategy":"validation","validationCode":"import os\ndef decodable_video_ready(path: str) -> bool:\n    return os.path.isfile(path) and os.path.getsize(path) > 0\n# plus a pre-check:\n# info = probe_video(path, timeout=30); info is not None","typeGuard":null,"tryCatchPattern":"try:\n    frames = list(iter_video_frames(path))\nexcept ValueError as e:\n    if \"No frames decoded\" in str(e):\n        handle_unsupported_video(path)  # reject upload / transcode","preventionTips":["probe_video before decoding every upload","Transcode exotic codecs to H.264/yuv420p on ingest","Use a full opencv build with FFmpeg support; verify cv2.getBuildInformation()","Reject zero-byte or streamless files at upload time"],"tags":["video","opencv","decoding","subprocess"],"backgroundTag":"no-video-stream-decoded","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}