{"record":{"id":"da7a6d44a1b2564c","repo":"affaan-m/ECC","slug":"frame-range-is-empty-or-outside-its-bounds","errorCode":null,"errorMessage":"frame range is empty or outside its bounds","messagePattern":"frame range is empty or outside its bounds","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/integration.py","lineNumber":72,"sourceCode":"    if type(value) is not int or value < minimum:\n        raise ValueError(\"frame/count must be an exact integer in range\")\n    return value\n\n\ndef _rate(value: Any) -> tuple[int, int]:\n    _object(value, {\"numerator\", \"denominator\"})\n    n, d = (_integer(value[k], 1) for k in (\"numerator\", \"denominator\"))\n    if math.gcd(n, d) != 1:\n        raise ValueError(\"fps must be a reduced positive rational\")\n    return n, d\n\n\ndef _range(value: Any, bounds: list[int] | None = None) -> list[int]:\n    if not isinstance(value, list) or len(value) != 2:\n        raise ValueError(\"range must contain two frame integers\")\n    start, end = (_integer(v) for v in value)\n    if start >= end or (bounds is not None and (start < bounds[0] or end > bounds[1])):\n        raise ValueError(\"frame range is empty or outside its bounds\")\n    return value\n\n\ndef _overlap(a: list[int], b: list[int]) -> bool:\n    return a[0] < b[1] and b[0] < a[1]\n\n\ndef _sha(value: Any) -> str:\n    if not isinstance(value, str) or not re.fullmatch(r\"[a-f0-9]{64}\", value):\n        raise ValueError(\"resolved SHA-256 required\")\n    return value\n\n\ndef _identity(info: os.stat_result) -> tuple:\n    return (info.st_dev, info.st_ino, info.st_size, info.st_mtime_ns, info.st_ctime_ns)\n\n\ndef _artifact(record: Any, *, parse_json: bool = False) -> Any:","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/integration.py#L54-L90","documentation":"After structural checks, _range enforces semantic validity: start must be strictly less than end, and if bounds are supplied the range must lie fully inside them; violations raise ValueError('frame range is empty or outside its bounds'). Zero-length or inverted ranges and out-of-bounds clips are rejected.","triggerScenarios":"Passing [100, 100] (empty), [200, 100] (inverted), or a range extending past the snapshot duration, e.g. [0, 9999] against bounds [0, 240].","commonSituations":"Off-by-one errors when computing end frames (exclusive vs inclusive end), clips trimmed to zero length, and ranges copied between sources with different total durations.","solutions":["Ensure end > start for every range and that ranges fit within the snapshot's frame bounds","Fix off-by-one math (range end is exclusive) and recompute from actual clip lengths","Clamp or drop clips whose ranges fall outside the media duration before building the bundle"],"exampleFix":"// before\nclip = {\"range\": [0, 9999]}  # exceeds 240-frame snapshot\n// after\nclip = {\"range\": [0, min(9999, snapshot_duration_frames)]}","handlingStrategy":"validation","validationCode":"def valid_range(r, bounds):\n    return r[0] < r[1] and bounds[0] <= r[0] and r[1] <= bounds[1]\nassert valid_range(clip_range, [0, duration_frames]), \"range empty or out of bounds\"","typeGuard":null,"tryCatchPattern":"try:\n    bundle = build_application_bundle(data)\nexcept ValueError as e:\n    if \"empty or outside its bounds\" in str(e):\n        print(\"clip range is zero-length, inverted, or exceeds media duration\")\n    else:\n        raise","preventionTips":["Compute end frames with a consistent exclusive-end convention","Clamp ranges to the snapshot/media duration before bundling","Drop or flag zero-length clips before they reach the bundle builder"],"tags":["frames","range","validation"],"backgroundTag":"value-out-of-range","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}