{"record":{"id":"715c0012c0e8584a","repo":"affaan-m/ECC","slug":"source-clip-is-too-short-for-its-no-repeat-cadence-slot","errorCode":null,"errorMessage":"source clip is too short for its no-repeat cadence slot","messagePattern":"source clip is too short for its no-repeat cadence slot","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/apply.py","lineNumber":95,"sourceCode":"    rate = timeline.fps_fraction(fps)\n    sources: dict[str, tuple[dict[str, Any], int]] = {}\n    for clip in media:\n        path = str(Path(clip[\"path\"]).expanduser().resolve())\n        # Floor rational capacity: rounding up could read past the source end.\n        capacity = math.floor(Fraction(str(clip[\"duration\"])) * rate)\n        # Accept a boundary serialized as a float only when the frame duration\n        # itself compares within the supplied duration; no broad epsilon.\n        if float((capacity + 1) / rate) <= clip[\"duration\"]:\n            capacity += 1\n        if path in sources:\n            raise ValueError(\"no-repeat media must contain unique normalized source paths\")\n        sources[path] = ({**clip, \"path\": path}, capacity)\n    if len(sources) < len(frame_counts):\n        raise ValueError(\"no-repeat plan requires more unique source clips\")\n    assignments = []\n    for (clip, capacity), count in zip(sources.values(), frame_counts):\n        if capacity < count:\n            raise ValueError(\"source clip is too short for its no-repeat cadence slot\")\n        assignments.append((clip, count))\n    return assignments\n\n\n\ndef plan_shots(cadence: dict[str, Any], target_duration: float) -> list[float]:\n    \"\"\"Propose shot durations filling ``target_duration`` at this cadence.\n\n    Samples from the reference's own shot-length distribution (seeded, like\n    the recovered ``Cadence.plan_shots``) so the plan inherits rhythm\n    variance instead of flattening into evenly spaced clips.\n    \"\"\"\n    target_duration = _positive(target_duration, \"target duration\")\n    durations = [\n        _positive(s[\"duration\"], \"cadence shot duration\")\n        for s in cadence.get(\"shots\", [])\n        if isinstance(s, dict) and _positive(s.get(\"duration\"), \"cadence shot duration\") > _MIN_SHOT\n    ]","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/apply.py#L77-L113","documentation":"In the final assignment loop, each unique source clip has a capacity — the maximum whole frames it can fill given its duration and the frame rate (`floor(duration * rate)`, plus one when the boundary fits). If a clip's capacity is less than the frame count its slot requires, the clip is too short for that slot and the strict no-repeat plan fails.","triggerScenarios":"A media clip shorter than the cadence slot it was matched to, e.g. a 0.1s clip assigned a 5-frame slot at 30fps (needs ~0.167s): `capacity < count` in the zip of sources to frame_counts.","commonSituations":"Mixing short B-roll clips with long measured shot cadences; cadence.json measured from a high-fps edit applied to short source footage; rounding at low fps making effective capacity smaller than expected.","solutions":["Replace the too-short clip with a longer source that covers the slot's frame count","Trim the cadence/mean_shot so slots require fewer frames","Regenerate cadence measurements to match the actual fps of the media","Pre-validate each clip: `floor(clip_duration * fps_fraction) >= frames_needed` before calling"],"exampleFix":"# before\n{\"path\": \"short.mp4\", \"duration\": 0.05}  # slot needs 3 frames @30fps\n# after\n{\"path\": \"longer.mp4\", \"duration\": 1.2}","handlingStrategy":"validation","validationCode":"rate = timeline.fps_fraction(fps)\nplanned = plan_shots(cadence, target)\nfor clip in media:\n    cap = math.floor(Fraction(str(clip[\"duration\"])) * rate)\n    if cap < 1:\n        raise ValueError(f\"clip {clip['path']} shorter than one frame\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pre-check each clip's frame capacity against the planned slot counts","Keep source clip lengths comparable to the measured shot cadence","Regenerate cadence at the same fps as the source media"],"tags":["media","no-repeat","capacity"],"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"}