affaan-m/ECC · error · ValueError
At least one video is required
Error message
At least one video is required
What it means
export_draft in capcut.py validates its inputs before building the CapCut draft: an empty files list means the timeline would have no video material, which the draft format cannot represent usefully.
Solutions
- Pass at least one existing video path in the files list
- Verify your concat file contains 'file <path>' lines if using read_concat
- Check that the glob/directory you sourced the list from actually contains videos (print len(files) before calling)
- Fix the working-directory or extension filter that emptied the list
Example fix
// before
files = read_concat('concat.txt') # only comments inside
export_draft(files, name='edit')
// after
files = read_concat('concat.txt')
assert files, 'concat file produced no entries'
export_draft(files, name='edit') Defensive patterns
Strategy: validation
Validate before calling
files = read_concat('concat.txt')
if not files:
raise SystemExit('no video entries found; concat file is empty or comment-only') Type guard
def has_videos(files):
return bool(files) and all(Path(f).is_file() for f in files) Try / catch
try:
export_draft(files, name=name)
except ValueError as e:
if 'At least one video' in str(e):
sys.exit('concat manifest or glob produced no videos') Prevention
- Assert len(files) > 0 before every export call
- Log the file list length at collection time (glob, concat, or CLI args)
- Check concat files for comments-only content
- Verify working directory when building lists with relative globs
When it happens
Trigger: Calling export_draft(files=[], ...) or passing a files list that ended up empty, e.g. because read_concat returned no 'file' lines from an empty or all-comment concat file.
Common situations: Concat file with only comments/blank lines; a glob like glob('*.mp4') matching nothing in the wrong working directory; upstream filtering removing all files before the call.
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
- Draft name must be a plain file name
- application bundle differs from its bound evidence
- at least one explicit seed is required
- At least one guided harness must be selected
- at least one non-empty
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/08eee5b84c5759f8.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/media/capcut.py:63
files,
drafts,
name,
width=1920,
height=1080,
fps=30,
overwrite=False,
cc=None,
probe=duration_of,
):
geometry(width, height, fps)
if overwrite:
raise ValueError("CapCut draft replacement is unsafe; choose a new name")
if not re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9_. -]{0,99}", name) or name.endswith(
"."
):
raise ValueError("Draft name must be a plain file name")
if not files:
raise ValueError("At least one video is required")
prepared = []
for filename in files:
path = Path(filename).resolve(strict=True)
duration = probe(path)
if not math.isfinite(duration) or duration <= 0:
raise ValueError(f"Invalid media duration: {path.name}")
prepared.append((str(path), duration))
if cc is None:
import pycapcut as cc
folder = cc.DraftFolder(str(drafts))
script = folder.create_draft(name, width, height, fps=fps, allow_replace=False)
script.add_track(cc.TrackType.video)
elapsed = 0
for filename, duration in prepared:
script.add_segment(
cc.VideoSegment(filename, cc.trange(f"{elapsed:.6f}s", f"{duration:.6f}s"))
)
elapsed += durationView on GitHub (pinned to 8321021c54)