vllm-project/vllm · error · ValueError
Could not read enough frames from video file {path} (expecte
Error message
Could not read enough frames from video file {path} (expected {num_frames} frames, got {len(frames)}) What it means
video_to_ndarrays() grabs frames sequentially and only decodes those in the sampled index set; if the stream ends early (cap.grab() fails) or retrieve() fails on sampled indices, fewer frames than the requested num_frames are collected. After np.stack, the count is checked and ValueError reports expected vs. obtained.
Source
Thrown at vllm/assets/video.py:68
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
frames = []
num_frames = num_frames if num_frames > 0 else total_frames
frame_indices = _sample_frame_indices(total_frames, num_frames)
for idx in range(total_frames):
ok = cap.grab() # next img
if not ok:
break
if idx in frame_indices: # only decompress needed
ret, frame = cap.retrieve()
if ret:
# OpenCV uses BGR format, we need to convert it to RGB
# for PIL and transformers compatibility
frames.append(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
frames = np.stack(frames)
if len(frames) < num_frames:
raise ValueError(
f"Could not read enough frames from video file {path}"
f" (expected {num_frames} frames, got {len(frames)})"
)
return frames
def video_to_pil_images_list(path: str, num_frames: int = -1) -> list[Image.Image]:
frames = video_to_ndarrays(path, num_frames)
return [Image.fromarray(frame) for frame in frames]
def video_get_metadata(path: str, num_frames: int = -1) -> dict[str, Any]:
import cv2
cap = cv2.VideoCapture(path)
if not cap.isOpened():
raise ValueError(f"Could not open video file {path}")
View on GitHub (pinned to c794754062)
Solutions
- Read total_frames via video_get_metadata first and clamp num_frames = min(num_frames, total_frames)
- Re-download or re-encode the video if it is truncated (verify with ffprobe -count_frames)
- Handle the ValueError per-item in a batch multimodal pipeline and skip/fallback that request
Example fix
# before frames = video_to_ndarrays(path, num_frames=64) # clip only has 50 decodable frames # after meta = video_get_metadata(path, num_frames=64) frames = video_to_ndarrays(path, num_frames=meta["total_num_frames"])
Defensive patterns
Strategy: validation
Validate before calling
meta = video_get_metadata(path, num_frames)
actual = meta["total_num_frames"]
if num_frames > actual:
num_frames = actual # clamp to decodable frame budget Try / catch
try:
frames = video_to_ndarrays(path, num_frames)
except ValueError as e:
if "Could not read enough frames" in str(e):
frames = video_to_ndarrays(path, -1) # take all frames
else:
raise Prevention
- Always clamp num_frames against metadata before decoding
- Per-item try/except in multimodal batch serving so one bad video fails one request, not the batch
When it happens
Trigger: Calling video_to_ndarrays(path, num_frames=N) where N exceeds frames actually decodable: truncated file, CAP_PROP_FRAME_COUNT lying (common with variable-frame-rate or streamed files), corrupted frames mid-file, or cv2codec partially failing.
Common situations: Asking for more frames than the clip contains (num_frames > total but metadata reported more), damaged user uploads, partially downloaded datasets where the tail is missing.
Related errors
- Could not open video file {path}
- 'mm_shm_cache_max_object_size_mb' should only be set when 'm
- 'mm_encoder_fp8_scale_path' and 'mm_encoder_fp8_scale_save_p
- 'mm_encoder_fp8_scale_save_path' cannot be used with 'mm_enc
- Invalid "device" in mm_processor_kwargs: {device!r}. Expecte
AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14).
Data as JSON: /api/errors/b968297ca3c4b06f.
Report an issue: GitHub.