{"record":{"id":"73ffd005b43a8d79","repo":"docling-project/docling","slug":"interval-seconds-must-be-0","errorCode":null,"errorMessage":"interval_seconds must be > 0","messagePattern":"interval_seconds must be > 0","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"docling/utils/video_frame_sampling.py","lineNumber":286,"sourceCode":"    buf = proc.stdout\n    count = len(buf) // frame_bytes\n    frames: list[tuple[float, Image.Image]] = []\n    for i in range(count):\n        chunk = buf[i * frame_bytes : (i + 1) * frame_bytes]\n        frames.append((i / fps, Image.frombytes(\"RGB\", (size, size), chunk)))\n    return frames\n\n\nclass FixedIntervalFrameSampler:\n    \"\"\"Sample one frame every ``interval_seconds`` from time zero.\"\"\"\n\n    def __init__(\n        self,\n        interval_seconds: float = 10.0,\n        max_frames: int | None = None,\n    ):\n        if interval_seconds <= 0:\n            raise ValueError(\"interval_seconds must be > 0\")\n        if max_frames is not None and max_frames <= 0:\n            raise ValueError(\"max_frames must be > 0 when set\")\n        self.interval_seconds = interval_seconds\n        self.max_frames = max_frames\n\n    def sample(self, video_path: Path) -> list[VideoFrame]:\n        _require_ffmpeg()\n        duration = _probe_duration(video_path)\n\n        frames: list[VideoFrame] = []\n        t = 0.0\n        # If duration is unknown (0.0), rely on extraction returning None at EOF.\n        while duration == 0.0 or t < duration:\n            if self.max_frames is not None and len(frames) >= self.max_frames:\n                break\n            image = _extract_frame(video_path, t)\n            if image is None:\n                break","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/utils/video_frame_sampling.py#L268-L304","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Pass a positive interval, e.g. FixedIntervalFrameSampler(interval_seconds=10.0) (the default).","Validate and clamp user-supplied values before construction: interval = max(interval, some_min) or raise a friendly error of your own.","If computing the interval from duration/frame count, guard against division by zero and against results <= 0."],"exampleFix":"# before\ninterval = duration / requested_frames  # requested_frames=0 -> ZeroDivisionError or 0\nsampler = FixedIntervalFrameSampler(interval_seconds=interval)\n\n# after\ninterval = duration / max(requested_frames, 1) if duration > 0 else 10.0\nsampler = FixedIntervalFrameSampler(interval_seconds=max(interval, 0.1))","handlingStrategy":"validation","validationCode":"if not (interval_seconds > 0):\n    raise ValueError(\"interval_seconds must be a positive number of seconds\")\nsampler = FixedIntervalFrameSampler(interval_seconds=interval_seconds)","typeGuard":null,"tryCatchPattern":"try:\n    sampler = FixedIntervalFrameSampler(interval_seconds=cfg.interval)\nexcept ValueError as exc:\n    raise ConfigError(f\"invalid sampler config: {exc}\") from exc","preventionTips":["Validate numeric config at load time, not at object construction deep in the pipeline.","Guard interval computations against division by zero and underflow to 0.","Use a sensible minimum (e.g. 0.1s) clamp for user-supplied intervals."],"tags":["video","validation","constructor"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}