invoke-ai/InvokeAI · error · TimeoutError

Timed out decoding frames from {video_path}

Error message

Timed out decoding frames from {video_path}

What it means

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.

Source

Thrown at invokeai/app/util/video_thumbnails.py:303

                if record_size > MAX_DECODED_FRAME_RECORD_BYTES:
                    raise ValueError(f"Decoded frame record exceeds {MAX_DECODED_FRAME_RECORD_BYTES} bytes")
                payload = read_exactly(record_size)
                put_result(("frame", np.load(io.BytesIO(payload), allow_pickle=False)))
        except (EOFError, ValueError, OSError) as error:
            put_result(("done", error))

    reader = threading.Thread(target=read_frames, name="video-frame-reader", daemon=True)
    stderr_reader = threading.Thread(target=drain_stderr, name="video-stderr-reader", daemon=True)
    reader.start()
    stderr_reader.start()
    deadline = time.monotonic() + (timeout if first_frame_timeout is None else first_frame_timeout)
    try:
        while True:
            if is_canceled is not None and is_canceled():
                raise CanceledException
            remaining = deadline - time.monotonic()
            if remaining <= 0:
                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

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Increase the timeout argument to iter_video_frames for high-resolution/long-GOP content.
  2. Validate/transcode the input with ffmpeg before decoding to rule out corruption.
  3. Check CPU availability for the worker subprocess (container CPU limits, cgroup throttling).
  4. Catch TimeoutError from iteration and skip/fail that video gracefully, terminating consumption of the generator.

Example fix

// before
for frame in iter_video_frames(path, timeout=30): ...  # TimeoutError mid-stream
// after
try:
    for frame in iter_video_frames(path, timeout=300):
        process(frame)
except TimeoutError:
    mark_video_failed(path, reason="decoder stall")
Defensive patterns

Strategy: try-catch

Validate before calling

# pre-decode sanity check
if probe_video(path, timeout=30) is None:
    raise UnsupportedMediaError(path)

Try / catch

try:
    for frame in iter_video_frames(path, timeout=300):
        process(frame)
except TimeoutError as e:
    if "Timed out decoding frames" in str(e):
        fail_job(path, "decoder stalled")

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/47f5d28c9f78d094. Report an issue: GitHub.