docling-project/docling · error · ValueError

interval_seconds must be > 0

Error message

interval_seconds must be > 0

What it means

ValueError raised by FixedIntervalFrameSampler.__init__ in docling/utils/video_frame_sampling.py when interval_seconds is zero or negative. The sampler extracts one frame every interval_seconds starting at t=0.0, so a non-positive interval would create an infinite sampling loop; the constructor rejects it immediately.

Source

Thrown at docling/utils/video_frame_sampling.py:286

    buf = proc.stdout
    count = len(buf) // frame_bytes
    frames: list[tuple[float, Image.Image]] = []
    for i in range(count):
        chunk = buf[i * frame_bytes : (i + 1) * frame_bytes]
        frames.append((i / fps, Image.frombytes("RGB", (size, size), chunk)))
    return frames


class FixedIntervalFrameSampler:
    """Sample one frame every ``interval_seconds`` from time zero."""

    def __init__(
        self,
        interval_seconds: float = 10.0,
        max_frames: int | None = None,
    ):
        if interval_seconds <= 0:
            raise ValueError("interval_seconds must be > 0")
        if max_frames is not None and max_frames <= 0:
            raise ValueError("max_frames must be > 0 when set")
        self.interval_seconds = interval_seconds
        self.max_frames = max_frames

    def sample(self, video_path: Path) -> list[VideoFrame]:
        _require_ffmpeg()
        duration = _probe_duration(video_path)

        frames: list[VideoFrame] = []
        t = 0.0
        # If duration is unknown (0.0), rely on extraction returning None at EOF.
        while duration == 0.0 or t < duration:
            if self.max_frames is not None and len(frames) >= self.max_frames:
                break
            image = _extract_frame(video_path, t)
            if image is None:
                break

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Pass a positive interval, e.g. FixedIntervalFrameSampler(interval_seconds=10.0) (the default).
  2. Validate and clamp user-supplied values before construction: interval = max(interval, some_min) or raise a friendly error of your own.
  3. If computing the interval from duration/frame count, guard against division by zero and against results <= 0.

Example fix

# before
interval = duration / requested_frames  # requested_frames=0 -> ZeroDivisionError or 0
sampler = FixedIntervalFrameSampler(interval_seconds=interval)

# after
interval = duration / max(requested_frames, 1) if duration > 0 else 10.0
sampler = FixedIntervalFrameSampler(interval_seconds=max(interval, 0.1))
Defensive patterns

Strategy: validation

Validate before calling

if not (interval_seconds > 0):
    raise ValueError("interval_seconds must be a positive number of seconds")
sampler = FixedIntervalFrameSampler(interval_seconds=interval_seconds)

Try / catch

try:
    sampler = FixedIntervalFrameSampler(interval_seconds=cfg.interval)
except ValueError as exc:
    raise ConfigError(f"invalid sampler config: {exc}") from exc

Prevention

When it happens

Trigger: Constructing FixedIntervalFrameSampler(interval_seconds=0), with a negative value, or with a computed interval that degenerates to 0 (e.g. interval = duration / n where n is 0 or duration is 0).

Common situations: Deriving the interval from user input or CLI flags without validation (e.g. --every 0); computing interval = total_seconds / desired_frames where desired_frames is very large relative to duration, causing floating-point underflow to 0; passing a config default that was accidentally set to 0 in YAML/JSON settings.

Related errors


AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14). Data as JSON: /api/errors/73ffd005b43a8d79. Report an issue: GitHub.