affaan-m/ECC · error · RuntimeError
decoded zero frames from
Error message
decoded zero frames from {path} What it means
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.
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
Example fix
// before frames = sample_frames(tiny_clip, n=30, skip_edges=0.2) # zero frames // after frames = 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)
Defensive patterns
Strategy: try-catch
Validate before calling
info = probe(path)
usable = max(0, int(info.frame_count * (1 - 2 * skip_edges)))
if usable <= 0: raise ValueError(f"clip too short to sample: {path}") Try / catch
try:
frames = sample_frames(path, n=12, skip_edges=0.1)
except RuntimeError as e:
if "decoded zero frames" in str(e):
frames = sample_frames(path, n=12, skip_edges=0.0) # retry without trimming
else: raise Prevention
- Validate the clip decodes with ffprobe -count_frames first
- Reduce skip_edges for very short clips
- Re-encode interrupted/corrupt downloads before processing
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/28368426f7f73615.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-distillation/scripts/taste/frames.py:81
cap.release()
return frames
lo = int(total * skip_edges)
hi = int(total * (1.0 - skip_edges))
idxs = np.linspace(lo, max(lo + 1, hi - 1), num=min(n, max(1, hi - lo)))
idxs = np.unique(idxs.astype(int))
out: list[np.ndarray] = []
for i in idxs:
cap.set(cv2.CAP_PROP_POS_FRAMES, int(i))
ok, bgr = cap.read()
if not ok:
continue
out.append(_prep(bgr, max_edge))
cap.release()
if not out:
raise RuntimeError(f"decoded zero frames from {path}")
return out
def _sequential_sample(cap, n: int, max_edge: int) -> list[np.ndarray]:
frames = []
while True:
ok, bgr = cap.read()
if not ok:
break
frames.append(bgr)
if not frames:
return []
idxs = np.unique(np.linspace(0, len(frames) - 1, num=min(n, len(frames))).astype(int))
return [_prep(frames[i], max_edge) for i in idxs]
def _prep(bgr: np.ndarray, max_edge: int) -> np.ndarray:
h, w = bgr.shape[:2]View on GitHub (pinned to 8321021c54)