sgl-project/sglang · error · ValueError

No frames decoded from video: {video_path!r}

Error message

No frames decoded from video: {video_path!r}

What it means

For V2V requests, Cosmos3 decodes the conditioning video with load_video; if decoding yields zero frames (corrupt file, unsupported codec, unreadable path), the stage cannot build condition latents and raises with the offending path.

Source

Thrown at python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/cosmos3.py:201

            )
            if not image_sources:
                raise ValueError("Cosmos3 I2V image list is empty")
            tensors: list[torch.Tensor] = []
            for src in image_sources:
                image = load_image(src)
                image = _resize_crop_pil(image, target_w, target_h)
                tensors.append(_pil_to_normalized_tensor(image))
            batch.preprocessed_image = torch.stack(tensors, dim=0).contiguous()
            self.log_info(
                f"Preprocessed {len(tensors)} conditioning image(s) to "
                f"{target_w}x{target_h}"
            )
            return batch

        if isinstance(video_path, str) and video_path:
            frames = load_video(video_path)
            if not frames:
                raise ValueError(f"No frames decoded from video: {video_path!r}")

            keep = (
                getattr(batch.sampling_params, "condition_video_keep", "first")
                or "first"
            )
            if keep not in ("first", "last"):
                raise ValueError(
                    f"condition_video_keep must be 'first' or 'last', got {keep!r}"
                )
            cond_indexes = self._resolve_condition_indexes(batch)
            # Encode the full output-length video so that the latent positions
            # we lock match what the decoder will reconstruct at those frame
            # indices. Encoding only the first ``max_idx*4+1`` frames produces
            # an out-of-distribution latent for the locked slots and decodes
            # to noise.
            num_source_frames = max(cond_indexes) * 4 + 1
            num_target_frames = batch.num_frames
            if keep == "last":

View on GitHub (pinned to 0132848349)

Solutions

  1. Verify the file plays locally and inspect it (ffprobe video.mp4) — confirm codec/container support and nonzero duration
  2. Re-download or re-encode the video (ffmpeg -i in.mp4 -c:v libx264 out.mp4)
  3. Check the path/URL is readable from the server process and ffmpeg is installed
  4. Add a pre-upload probe in your client that rejects videos with 0 frames

Example fix

# before
req = {"video_path": "corrupt.mp4", "prompt": "..."}
# after
# re-encode to a supported codec first
# ffmpeg -i corrupt.mp4 -c:v libx264 -pix_fmt yuv420p fixed.mp4
req = {"video_path": "fixed.mp4", "prompt": "..."}
Defensive patterns

Strategy: validation

Validate before calling

import decord, os
assert os.path.exists(video_path) and os.path.getsize(video_path) > 0
vr = decord.VideoReader(video_path)
assert len(vr) > 0, "video has no frames"

Try / catch

catch ValueError matching 'No frames decoded' and route the item to a re-encode/reject path instead of retrying

Prevention

When it happens

Trigger: video_path is a non-empty string but load_video(video_path) returns an empty list — corrupt/truncated video, wrong container/codec, missing ffmpeg/dec support, or a URL/path the loader can't open.

Common situations: Downloading a partially-written mp4; feeding .avi/.webm the decode stack doesn't support; containerized deployment without ffmpeg; wrong mount path so the file is empty.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/99d7a89c8e419594. Report an issue: GitHub.