{"record":{"id":"463a7ee64021f514","repo":"invoke-ai/InvokeAI","slug":"message-detail","errorCode":null,"errorMessage":"{message}: {detail}","messagePattern":"\\{message\\}: \\{detail\\}","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"invokeai/app/util/video_thumbnails.py","lineNumber":321,"sourceCode":"                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\n            if return_code != 0:\n                stderr_reader.join(timeout=1)\n                detail = read_stderr()\n                message = f\"Unable to decode video at {video_path}\"\n                raise ValueError(f\"{message}: {detail}\" if detail else message) from value\n            return\n    finally:\n        memory_monitor_stop.set()\n        memory_monitor.join(timeout=1)\n        stopped.set()\n        if proc.poll() is None:\n            _terminate_process_tree(proc)\n        proc.stdout.close()\n        proc.wait()\n        reader.join(timeout=1)\n        stderr_reader.join(timeout=1)\n        proc.stderr.close()\n","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/util/video_thumbnails.py#L303-L339","documentation":"Raised (as TimeoutError) when, after the worker sent its final message, proc.wait() did not observe exit within the remaining timeout — the decoder process failed to terminate in time. The process tree is killed first, and any captured stderr is appended to the message for diagnosis. Message text is 'Timed out waiting for video decoder worker for {path}: {stderr tail}'.","triggerScenarios":"iter_video_frames reaching end-of-stream while the worker process lingers past the deadline — e.g. an ffmpeg child that ignores shutdown, a wedged worker after producing its last frame, or a timeout so small that even process teardown exceeds it.","commonSituations":"Very tight timeouts on slow/loaded machines; ffmpeg child processes stuck on a broken pipe or network source (e.g. decoding from an HTTP URL that stalls); zombie process accumulation preventing clean reaping.","solutions":["Increase the timeout so the worker has time to exit cleanly after the last frame.","Avoid decoding directly from flaky network URLs — copy to local disk first, then decode.","Check for stuck ffmpeg subprocesses (ps aux | grep ffmpeg) and kill them; investigate why they refuse to exit.","Read the stderr detail in the exception — it usually names the underlying decoder problem."],"exampleFix":"// before\nframes = list(iter_video_frames(url, timeout=15))  # TimeoutError waiting for worker\n// after\nlocal = download_to_temp(url)\ntry:\n    frames = list(iter_video_frames(local, timeout=120))\nfinally:\n    local.unlink()","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    for frame in iter_video_frames(path, timeout=120):\n        ...\nexcept TimeoutError as e:\n    if \"waiting for video decoder worker\" in str(e):\n        log.warning(\"decoder lingered: %s\", e)  # stderr detail is in message\n        cleanup_stray_ffmpeg()","preventionTips":["Allow teardown time in the timeout budget","Decode from local files, not flaky network sources","Monitor for stray ffmpeg child processes","Escalate timeout if stderr shows slow shutdown"],"tags":["video","timeout","subprocess","process-tree"],"backgroundTag":"subprocess-timeout","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}