invoke-ai/InvokeAI · error · TimeoutError
{message}: {detail}
Error message
{message}: {detail} What it means
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}'.
Source
Thrown at invokeai/app/util/video_thumbnails.py:321
raise TimeoutError(f"Timed out decoding frames from {video_path}")
try:
kind, value = results.get(timeout=min(0.1, remaining))
except queue.Empty:
continue
if kind == "frame":
if not isinstance(value, np.ndarray):
raise ValueError(f"Decoder returned an invalid frame for {video_path}")
yield value
deadline = time.monotonic() + timeout
continue
try:
return_code = proc.wait(timeout=min(1, timeout))
except subprocess.TimeoutExpired as error:
_terminate_process_tree(proc)
stderr_reader.join(timeout=1)
detail = read_stderr()
message = f"Timed out waiting for video decoder worker for {video_path}"
raise TimeoutError(f"{message}: {detail}" if detail else message) from error
if return_code != 0:
stderr_reader.join(timeout=1)
detail = read_stderr()
message = f"Unable to decode video at {video_path}"
raise ValueError(f"{message}: {detail}" if detail else message) from value
return
finally:
memory_monitor_stop.set()
memory_monitor.join(timeout=1)
stopped.set()
if proc.poll() is None:
_terminate_process_tree(proc)
proc.stdout.close()
proc.wait()
reader.join(timeout=1)
stderr_reader.join(timeout=1)
proc.stderr.close()
View on GitHub (pinned to 0b6a024f2f)
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.
Example fix
// before
frames = list(iter_video_frames(url, timeout=15)) # TimeoutError waiting for worker
// after
local = download_to_temp(url)
try:
frames = list(iter_video_frames(local, timeout=120))
finally:
local.unlink() Defensive patterns
Strategy: try-catch
Try / catch
try:
for frame in iter_video_frames(path, timeout=120):
...
except TimeoutError as e:
if "waiting for video decoder worker" in str(e):
log.warning("decoder lingered: %s", e) # stderr detail is in message
cleanup_stray_ffmpeg() Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Video decode worker timed out after {timeout}s
- No frames decoded from {video_path}
- Unable to open video decoder output stream
- Timed out decoding frames from {video_path}
- Timed out waiting to decode frames from {video_path}
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/463a7ee64021f514.
Report an issue: GitHub.