{"record":{"id":"47f5d28c9f78d094","repo":"invoke-ai/InvokeAI","slug":"timed-out-decoding-frames-from-video-path","errorCode":null,"errorMessage":"Timed out decoding frames from {video_path}","messagePattern":"Timed out decoding frames from (.+?)","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"invokeai/app/util/video_thumbnails.py","lineNumber":303,"sourceCode":"                if record_size > MAX_DECODED_FRAME_RECORD_BYTES:\n                    raise ValueError(f\"Decoded frame record exceeds {MAX_DECODED_FRAME_RECORD_BYTES} bytes\")\n                payload = read_exactly(record_size)\n                put_result((\"frame\", np.load(io.BytesIO(payload), allow_pickle=False)))\n        except (EOFError, ValueError, OSError) as error:\n            put_result((\"done\", error))\n\n    reader = threading.Thread(target=read_frames, name=\"video-frame-reader\", daemon=True)\n    stderr_reader = threading.Thread(target=drain_stderr, name=\"video-stderr-reader\", daemon=True)\n    reader.start()\n    stderr_reader.start()\n    deadline = time.monotonic() + (timeout if first_frame_timeout is None else first_frame_timeout)\n    try:\n        while True:\n            if is_canceled is not None and is_canceled():\n                raise CanceledException\n            remaining = deadline - time.monotonic()\n            if remaining <= 0:\n                raise TimeoutError(f\"Timed out decoding frames from {video_path}\")\n            try:\n                kind, value = results.get(timeout=min(0.1, remaining))\n            except queue.Empty:\n                continue\n            if kind == \"frame\":\n                if not isinstance(value, np.ndarray):\n                    raise ValueError(f\"Decoder returned an invalid frame for {video_path}\")\n                yield value\n                deadline = time.monotonic() + timeout\n                continue\n            try:\n                return_code = proc.wait(timeout=min(1, timeout))\n            except subprocess.TimeoutExpired as error:\n                _terminate_process_tree(proc)\n                stderr_reader.join(timeout=1)\n                detail = read_stderr()\n                message = f\"Timed out waiting for video decoder worker for {video_path}\"\n                raise TimeoutError(f\"{message}: {detail}\" if detail else message) from error","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/util/video_thumbnails.py#L285-L321","documentation":"Raised by the streamed frame iterator when no result arrives from the decoder worker within the inactivity `timeout` window. The deadline is reset on every frame, so this fires only when the worker stalls entirely mid-decode. It prevents callers of iter_video_frames from hanging forever on a wedged decoder.","triggerScenarios":"Calling iter_video_frames on a video where the decode worker hangs (corrupt file, deadlocked ffmpeg child), or where decoding the first frame alone takes longer than `timeout`; also if the consumer blocks the generator so long that inter-frame gaps exceed timeout? No — the deadline resets after each yielded frame, so it only triggers when the worker produces nothing within timeout.","commonSituations":"Videos with damaged moov atoms or corrupt packets stalling ffmpeg; extremely large first GOP on long-GOP 4K footage with a short timeout; CPU-starved containers making decode slower than timeout.","solutions":["Increase the timeout argument to iter_video_frames for high-resolution/long-GOP content.","Validate/transcode the input with ffmpeg before decoding to rule out corruption.","Check CPU availability for the worker subprocess (container CPU limits, cgroup throttling).","Catch TimeoutError from iteration and skip/fail that video gracefully, terminating consumption of the generator."],"exampleFix":"// before\nfor frame in iter_video_frames(path, timeout=30): ...  # TimeoutError mid-stream\n// after\ntry:\n    for frame in iter_video_frames(path, timeout=300):\n        process(frame)\nexcept TimeoutError:\n    mark_video_failed(path, reason=\"decoder stall\")","handlingStrategy":"try-catch","validationCode":"# pre-decode sanity check\nif probe_video(path, timeout=30) is None:\n    raise UnsupportedMediaError(path)","typeGuard":null,"tryCatchPattern":"try:\n    for frame in iter_video_frames(path, timeout=300):\n        process(frame)\nexcept TimeoutError as e:\n    if \"Timed out decoding frames\" in str(e):\n        fail_job(path, \"decoder stalled\")","preventionTips":["Use generous inactivity timeouts for high-res/long-GOP video","Pre-verify files with probe_video or ffprobe","Ensure adequate CPU for worker subprocesses","Handle cancellation so stalled jobs can be aborted early"],"tags":["video","timeout","streaming","decoding"],"backgroundTag":"stream-inactivity-timeout","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}