{"record":{"id":"28368426f7f73615","repo":"affaan-m/ECC","slug":"decoded-zero-frames-from-path-283684","errorCode":null,"errorMessage":"decoded zero frames from {path}","messagePattern":"decoded zero frames from (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"skills/taste-distillation/scripts/taste/frames.py","lineNumber":81,"sourceCode":"        cap.release()\n        return frames\n\n    lo = int(total * skip_edges)\n    hi = int(total * (1.0 - skip_edges))\n    idxs = np.linspace(lo, max(lo + 1, hi - 1), num=min(n, max(1, hi - lo)))\n    idxs = np.unique(idxs.astype(int))\n\n    out: list[np.ndarray] = []\n    for i in idxs:\n        cap.set(cv2.CAP_PROP_POS_FRAMES, int(i))\n        ok, bgr = cap.read()\n        if not ok:\n            continue\n        out.append(_prep(bgr, max_edge))\n    cap.release()\n\n    if not out:\n        raise RuntimeError(f\"decoded zero frames from {path}\")\n    return out\n\n\ndef _sequential_sample(cap, n: int, max_edge: int) -> list[np.ndarray]:\n    frames = []\n    while True:\n        ok, bgr = cap.read()\n        if not ok:\n            break\n        frames.append(bgr)\n    if not frames:\n        return []\n    idxs = np.unique(np.linspace(0, len(frames) - 1, num=min(n, len(frames))).astype(int))\n    return [_prep(frames[i], max_edge) for i in idxs]\n\n\ndef _prep(bgr: np.ndarray, max_edge: int) -> np.ndarray:\n    h, w = bgr.shape[:2]","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-distillation/scripts/taste/frames.py#L63-L99","documentation":"sample_frames() raises when the video opens successfully but zero frames could actually be decoded (out list empty). This happens with headers that parse but whose stream data is unreadable, or when skip_edges trimming plus a tiny frame count leaves nothing to grab.","triggerScenarios":"Calling sample_frames() on a video whose container opens but decodes no frames (corrupt stream, unsupported codec variant), or on a very short clip where requested n and skip_edges fraction exclude all frames.","commonSituations":"Interrupted encode/download leaving a valid header and truncated payload; 1-2 frame clips combined with a large skip_edges value; DRM or broken moov atom; live recordings with no decodable frames.","solutions":["Verify the video decodes elsewhere (ffprobe -count_frames) to confirm corruption","Re-encode with ffmpeg to repair the stream before sampling","Reduce skip_edges or n so sampling covers the actual frame count for short clips","Fall back to _sequential_sample logic by lowering requested frame counts"],"exampleFix":"// before\nframes = sample_frames(tiny_clip, n=30, skip_edges=0.2)  # zero frames\n// after\nframes = sample_frames(tiny_clip, n=30, skip_edges=0.0) if frame_count <= 10 else sample_frames(tiny_clip, n=30, skip_edges=0.2)","handlingStrategy":"try-catch","validationCode":"info = probe(path)\nusable = max(0, int(info.frame_count * (1 - 2 * skip_edges)))\nif usable <= 0: raise ValueError(f\"clip too short to sample: {path}\")","typeGuard":null,"tryCatchPattern":"try:\n    frames = sample_frames(path, n=12, skip_edges=0.1)\nexcept RuntimeError as e:\n    if \"decoded zero frames\" in str(e):\n        frames = sample_frames(path, n=12, skip_edges=0.0)  # retry without trimming\n    else: raise","preventionTips":["Validate the clip decodes with ffprobe -count_frames first","Reduce skip_edges for very short clips","Re-encode interrupted/corrupt downloads before processing"],"tags":["video","decoding","opencv"],"backgroundTag":"empty-result-set","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}