sgl-project/sglang · error · ValueError

bad metadata: dur={duration} h={original_height} w={original

Error message

bad metadata: dur={duration} h={original_height} w={original_width}

What it means

Raised by extract_frames_v2 in dots_note_omni_video_core when the video decoder's metadata reports a non-positive duration, height, or width. Frame extraction needs valid dimensions and duration to compute the sampling grid, so it aborts immediately.

Source

Thrown at python/sglang/srt/multimodal/processors/dots_note_omni_video_core/preprocess.py:121

    decoder,
    seq_length,
    visual_budget,
    *,
    pf_floor=V2_PF_FLOOR,
    pf_ceil=V2_PF_CEIL,
    fps_cap=V2_FPS_CAP,
    fps_min=V2_FPS_MIN,
    overhead=V2_OVH,
    jpeg_quality=85,
):
    """Decode, resize, and JPEG-encode frames selected by the v2 policy."""
    metadata = decoder.metadata
    duration = float(metadata.duration_seconds or 0)
    original_height = int(metadata.height)
    original_width = int(metadata.width)
    total_frames = int(metadata.num_frames or 0)
    if duration <= 0 or original_height <= 0 or original_width <= 0:
        raise ValueError(
            f"bad metadata: dur={duration} h={original_height} w={original_width}"
        )
    original_fps = float(metadata.average_fps or 0) or 25.0
    if total_frames <= 0:
        total_frames = max(1, int(duration * original_fps))

    aligned_height = max(ALIGN, round(original_height / ALIGN) * ALIGN)
    aligned_width = max(ALIGN, round(original_width / ALIGN) * ALIGN)
    original_patches = (aligned_height // ALIGN) * (aligned_width // ALIGN)
    num_frames, _, target_patches = v2_solve_degrade(
        visual_budget,
        duration,
        original_patches,
        original_fps,
        seq_length,
        fps_cap=fps_cap,
        fps_min=fps_min,
        pf_floor=pf_floor,

View on GitHub (pinned to 0132848349)

Solutions

  1. Re-encode/remux the file with ffmpeg (ffmpeg -i in.mp4 -c copy fixed.mp4) to rebuild clean metadata
  2. Verify the file plays and probe it: ffprobe shows duration/width/height > 0 before sending
  3. Reject or replace videos with missing metadata in your ingest pipeline

Example fix

# before
resp = requests.get(url); open('v.mp4','wb').write(resp.content)  # may be truncated
# after
import subprocess; subprocess.run(['ffmpeg','-v','error','-i','v_raw.mp4','-c','copy','v.mp4'], check=True)
# then send v.mp4
Defensive patterns

Strategy: validation

Validate before calling

import subprocess, json
meta = json.loads(subprocess.check_output(['ffprobe','-v','error','-select_streams','v:0','-show_entries','stream=width,height:format=duration','-of','json', path]))
w = meta['streams'][0].get('width', 0); h = meta['streams'][0].get('height', 0)
dur = float(meta['format'].get('duration', 0) or 0)
assert w > 0 and h > 0 and dur > 0, f'bad metadata: dur={dur} h={h} w={w}'

Try / catch

try:
    frames = extract_frames_v2(video_path)
except ValueError as e:
    if e.args[0].startswith('bad metadata'):
        subprocess.run(['ffmpeg','-v','error','-i',video_path,'-c','copy',fixed], check=True)
        frames = extract_frames_v2(fixed)  # retry with remuxed file

Prevention

When it happens

Trigger: Feeding a corrupt/truncated video file, a non-video file, or a stream whose container metadata is missing (duration_seconds None -> 0, or height/width 0) through process_sample_video / extract_frames_v2.

Common situations: Partially downloaded or re-muxed videos with stripped headers; placeholder/zero-byte files; some WebM/MKV variants where decord/torchaudio metadata fields are unpopulated.

Related errors


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