{"record":{"id":"e7e754e37325725a","repo":"invoke-ai/InvokeAI","slug":"decoder-returned-an-invalid-frame-for-video-path","errorCode":null,"errorMessage":"Decoder returned an invalid frame for {video_path}","messagePattern":"Decoder returned an invalid frame for (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/app/util/video_thumbnails.py","lineNumber":310,"sourceCode":"    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\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:","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/util/video_thumbnails.py#L292-L328","documentation":"Raised when the decode worker sends a result tagged 'frame' whose payload is not a numpy ndarray, i.e. the worker/parent protocol was violated or the payload was corrupted. In normal operation this is unreachable; it is a defensive invariant check on the IPC queue. It indicates a bug in the worker or a mismatch between worker and library versions.","triggerScenarios":"A decode worker built from a different (mixed-install) version of the library emitting frames in an unexpected format; a monkeypatched or replaced worker script; tampering with the results queue protocol in tests.","commonSituations":"Mixed old/new package installs where the spawned worker script comes from a stale site-packages (e.g. after an upgrade without restarting long-running workers); custom forks altering the frame payload type.","solutions":["Restart the application/worker pool so the spawned decode-worker script matches the installed library version.","Reinstall the package cleanly (pip install --force-reinstall) to remove duplicate/mixed copies in site-packages.","Remove any monkeypatching or custom worker script overrides of the decode command.","If you maintain a fork, keep the worker protocol ('frame' → np.ndarray, 'done'/'error') in sync with the parent."],"exampleFix":"// before\n# worker emits frame as list\nresults.put((\"frame\", frame.tolist()))  # parent: ValueError invalid frame\n// after\nresults.put((\"frame\", np.asarray(frame)))  # or stop customizing the worker","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"import numpy as np\ndef is_valid_frame(value) -> bool:\n    return isinstance(value, np.ndarray)","tryCatchPattern":"try:\n    for frame in iter_video_frames(path):\n        ...\nexcept ValueError as e:\n    if \"invalid frame\" in str(e):\n        restart_worker_pool()  # version/protocol mismatch","preventionTips":["Restart workers after every package upgrade","Avoid mixed-install site-packages (use virtualenvs/containers)","Do not monkeypatch the decode worker script or queue protocol","Pin library versions between parent and worker images"],"tags":["video","ipc","protocol","numpy","internal-error"],"backgroundTag":"ipc-protocol-violation","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}