affaan-m/ECC · error · ValueError
clip has no 'path
Error message
clip {i} has no 'path' What it means
Structural guard in _normalise: a clip in the input list lacks the required 'path' key, so the timeline builder cannot locate the media file. The 0-based clip index at fault is included in the message.
Solutions
- Add the 'path' key to each clip dict with a non-empty string.
- Rename your key (e.g. 'src' -> 'path') or map it before calling: `{'path': c['src'], 'duration': c['dur']}`.
- Validate the clips list before building: check every clip has a truthy 'path'.
- Fix upstream data extraction that emitted null paths.
Example fix
// before
clips = [{"name": "intro", "duration": 3.0}]
// after
clips = [{"name": "intro", "path": "media/intro.mp4", "duration": 3.0}] Defensive patterns
Strategy: validation
Validate before calling
def validate_clips_have_paths(clips):
for i, c in enumerate(clips):
if not str(c.get('path') or '').strip():
raise ValueError(f"clip {i} has no 'path'")
return True Type guard
def is_valid_clip(c) -> bool:
return isinstance(c, dict) and bool(str(c.get('path') or '').strip()) Try / catch
try:
xml = build_fcpxml(clips, fps=30)
except ValueError as e:
if "has no 'path'" in str(e):
logger.error('invalid clip manifest: %s', e)
raise Prevention
- Standardize clip dicts with a dataclass/TypedDict requiring 'path'
- Validate clip manifests (JSON schema) before building timelines
- Rename alternate keys ('src', 'file') to 'path' at ingestion
- Reject null paths at the data-collection step, not the build step
When it happens
Trigger: Calling build_fcpxml or build_edl with a clips list where an entry is missing the 'path' key, has path=None, or path='' (empty string coerces to falsy).
Common situations: Building clips programmatically and forgetting the key; JSON clip manifests with null paths for placeholder clips; a key-name mismatch such as 'file' or 'src' instead of 'path'.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- -32602
- artifact path must be a non-empty relative path
- assets must be a nonempty list
- base_track_count exceeds target video tracks
- built an invalid spec
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/f43c41ec6474e162.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/taste/timeline.py:218
# ---------------------------------------------------------------------------
# clip normalisation
# ---------------------------------------------------------------------------
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 outView on GitHub (pinned to 8321021c54)