{"record":{"id":"7de955bdeb6bc586","repo":"roboflow/supervision","slug":"reader-thread-raised-item","errorCode":null,"errorMessage":"Reader thread raised: {item}","messagePattern":"Reader thread raised: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/supervision/utils/video.py","lineNumber":368,"sourceCode":"            while not stop_event.is_set():\n                try:\n                    frame_queue.put(sentinel, timeout=0.1)\n                    return\n                except Full:\n                    pass\n\n    thread = threading.Thread(target=reader, daemon=True)\n    thread.start()\n    try:\n        while True:\n            try:\n                item = frame_queue.get(timeout=0.5)\n            except Empty:\n                if not thread.is_alive():\n                    break\n                continue\n            if isinstance(item, BaseException):\n                raise RuntimeError(f\"Reader thread raised: {item!r}\") from item\n            if item is None:\n                break\n            yield item\n    finally:\n        stop_event.set()\n        thread.join(timeout=2.0)\n\n\ndef process_video(\n    source_path: str,\n    target_path: str,\n    callback: Callable[[npt.NDArray[np.uint8], int], npt.NDArray[np.uint8]],\n    *,\n    max_frames: int | None = None,\n    prefetch: int = 32,\n    writer_buffer: int = 32,\n    show_progress: bool = False,\n    progress_message: str = \"Processing video\",","sourceCodeStart":350,"sourceCodeEnd":386,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/utils/video.py#L350-L386","documentation":"Raised by the frame queue consumer inside _prefetched_frames_generator (src/supervision/utils/video.py) when the background reader thread put an exception object into the queue instead of a frame. The consumer wraps it in RuntimeError, chaining the original exception, so the message names the underlying failure that occurred while opening or reading the video on the worker thread.","triggerScenarios":"Calling sv.get_video_frames_generator(path, prefetch=N) where the reader thread hits an error — e.g. the video cannot be opened, a grab()/retrieve() fails mid-stream, or the file is truncated. The exception travels through the queue and is re-raised on the main thread during iteration.","commonSituations":"A video becomes unreadable or is deleted after the generator is created; truncated recordings from killed processes; network streams dropping mid-read; the error text 'Reader thread raised: ...' is a wrapper — the real cause follows after the colon and via __cause__.","solutions":["Read the tail of the message and the chained __cause__ to find the real failure, then fix that (usually file/codec related).","Verify the source video opens synchronously first: sv.get_video_frames_generator(path) with prefetch=0 to get the raw error.","Guard per-file processing in a try/except so one bad video does not kill a batch job.","If the file is truncated, repair or re-encode it with ffmpeg before processing."],"exampleFix":"// before\nfor frame in sv.get_video_frames_generator(path, prefetch=8):\n    ...  # RuntimeError: Reader thread raised: ...\n\n// after\ntry:\n    for frame in sv.get_video_frames_generator(path, prefetch=8):\n        ...\nexcept RuntimeError as e:\n    log.warning('skipping %s: %s', path, e.__cause__ or e)","handlingStrategy":"try-catch","validationCode":"probe = cv2.VideoCapture(path)\nreadable = probe.isOpened()\nprobe.release()\nif not readable:\n    raise RuntimeError(f'video not readable: {path}')","typeGuard":null,"tryCatchPattern":"try:\n    for frame in sv.get_video_frames_generator(path, prefetch=prefetch):\n        process(frame)\nexcept RuntimeError as e:\n    if 'Reader thread raised' in str(e) and e.__cause__ is not None:\n        log.warning('reader failure on %s: %r', path, e.__cause__)\n        continue  # skip to next file in a batch\n    raise","preventionTips":["Treat 'Reader thread raised' as a wrapper; always inspect __cause__ for the real error.","Wrap per-video processing in try/except in batch pipelines.","Verify file integrity (ffprobe) before enabling prefetch on untrusted inputs."],"tags":["video","threading","exception-chaining","opencv"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}