affaan-m/ECC · error · ValueError
clip ( ) has non-positive duration
Error message
clip {i} ({path}) has non-positive duration {dur!r} What it means
_normalise() rejects clips whose duration is missing, zero, or negative (float(c.get('duration') or 0.0) then dur <= 0). A timeline event with no positive length is meaningless, so the builder raises with the clip index, path, and offending duration.
Solutions
- Set a positive 'duration' (seconds) on every clip dict
- Filter or repair zero-duration clips before building
- Check upstream in/out-point math (end - start) for degenerate ranges
- Measure clip durations with ffprobe and fill them into the manifest
Example fix
// before
clips = [{"path": "a.mp4", "duration": 0}]
// after
clips = [{"path": "a.mp4", "duration": max(0.04, end - start)}] Defensive patterns
Strategy: validation
Validate before calling
bad = [i for i, c in enumerate(clips) if float(c.get('duration') or 0) <= 0]
if bad:
raise ValueError(f'clips with non-positive duration: {bad}') Type guard
def has_positive_duration(c: dict) -> bool:
try:
return float(c.get('duration') or 0) > 0
except (TypeError, ValueError):
return False Try / catch
try:
build_edl(clips, fps=24)
except ValueError as e:
if 'non-positive duration' in str(e):
logger.error('bad clip durations: %s', e)
raise Prevention
- Compute durations as max(min_duration, end - start)
- Measure clip durations with ffprobe before manifest generation
- Reject degenerate cuts (start >= end) upstream
When it happens
Trigger: Calling build_fcpxml/build_edl with a clip {"path": p} lacking 'duration' (None -> 0.0), or duration=0, or a negative value from a bad cut calculation.
Common situations: Duration not yet measured when the manifest was generated; end-start computing to 0 for zero-length segments; None passed where seconds were expected.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- clip has no 'path
- clip ( ) has non-positive duration
- base_track_count exceeds target video tracks
- clip has no 'path
- clip ( ) has non-positive duration
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/e50f29c320fd4182.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-distillation/scripts/taste/timeline.py:221
# ---------------------------------------------------------------------------
def _normalise(clips: Iterable[dict], fps: float | Fraction) -> list[dict]:
"""Validate clips and pre-compute integer frame counts and offsets.
Returns dicts with ``path``, ``name``, ``frames`` (int, >= 1) and
``offset_frames`` (int). Working in frames from here down is what makes the
sequence duration exactly the sum of the clip durations.
"""
out: list[dict] = []
offset = 0
for i, c in enumerate(clips):
path = str(c.get("path") or "")
if not path:
raise ValueError(f"clip {i} has no 'path'")
dur = float(c.get("duration") or 0.0)
if dur <= 0:
raise ValueError(f"clip {i} ({path}) has non-positive duration {dur!r}")
frames = max(1, seconds_to_frames(dur, fps)) # never emit a zero-length event
name = str(c.get("name") or Path(path).stem)
out.append(
{
"path": path,
"name": name,
"frames": frames,
"offset_frames": offset,
"seconds": dur,
}
)
offset += frames
if not out:
raise ValueError("no clips to write - a timeline needs at least one event")
return out
def _file_uri(path: str) -> str:View on GitHub (pinned to 8321021c54)