{"record":{"id":"437f24057db7c651","repo":"microsoft/autogen","slug":"timestamp-timestamp-2f-s-is-out-of-range-0s-d","errorCode":null,"errorMessage":"Timestamp {timestamp:.2f}s is out of range [0s, {duration:.2f}s]","messagePattern":"Timestamp (.+?)s is out of range \\[0s, (.+?)s\\]","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"python/packages/autogen-ext/src/autogen_ext/agents/video_surfer/tools.py","lineNumber":170,"sourceCode":"    if not cap.isOpened():\n        raise IOError(f\"Cannot open video file {video_path}\")\n\n    fps = cap.get(cv2.CAP_PROP_FPS)\n    total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)\n    duration = total_frames / fps\n\n    for timestamp in timestamps:\n        if 0 <= timestamp <= duration:\n            frame_number = int(timestamp * fps)\n            cap.set(cv2.CAP_PROP_POS_FRAMES, frame_number)\n            ret, frame = cap.read()\n            if ret:\n                # Append the timestamp and frame to the list\n                screenshots.append((timestamp, frame))\n            else:\n                raise IOError(f\"Failed to capture frame at {timestamp:.2f}s\")\n        else:\n            raise ValueError(f\"Timestamp {timestamp:.2f}s is out of range [0s, {duration:.2f}s]\")\n\n    cap.release()\n    return screenshots\n","sourceCodeStart":152,"sourceCodeEnd":174,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/agents/video_surfer/tools.py#L152-L174","documentation":"get_screenshots() computes duration = total_frames / fps and raises ValueError for any timestamp outside [0, duration] (inclusive). This is intentional input validation before seeking — OpenCV seeking outside the stream either fails or misbehaves, so the tool rejects the request outright. Note fps can be 0.0 for broken streams, making duration inf/NaN and validation unreliable.","triggerScenarios":"Passing a negative timestamp, a timestamp larger than the video length (e.g. asking for 60s on a 30s clip), or timestamps derived from a different video or from hallucinated LLM output.","commonSituations":"Agents guessing timestamps without first calling get_video_length(), unit conversions (milliseconds passed as seconds), mixed-up files in a processing queue.","solutions":["Call get_video_length(video_path) first and clamp timestamps into [0, duration]","Filter: timestamps = [t for t in timestamps if 0 <= t <= duration]","Ensure timestamps are in seconds, not milliseconds","Guard against fps == 0 (corrupt stream) by re-encoding the source video"],"exampleFix":"// before\nshots = get_screenshots(video, [0, 500, 900])  # ms mistaken for s -> ValueError\n\n// after\nshots = get_screenshots(video, [t / 1000.0 for t in (0, 500, 900)])  # seconds","handlingStrategy":"validation","validationCode":"import re\nfrom autogen_ext.agents.video_surfer.tools import get_video_length\ndef valid_timestamps(video: str, ts_list: list[float]) -> list[float]:\n    dur = float(re.search(r'[\\d.]+', get_video_length(video)).group())\n    return [t for t in ts_list if 0.0 <= t <= dur]","typeGuard":null,"tryCatchPattern":"try:\n    shots = get_screenshots(video, timestamps)\nexcept ValueError as e:\n    if 'out of range' in str(e):\n        timestamps = valid_timestamps(video, timestamps)\n        shots = get_screenshots(video, timestamps)\n    else:\n        raise","preventionTips":["Always call get_video_length before sampling timestamps","Standardize on seconds everywhere in your pipeline","Filter LLM-proposed timestamps against the known duration before executing"],"tags":["validation","timestamp","video","opencv","video-surfer"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}