affaan-m/ECC · error · ValueError
nothing to concatenate
Error message
nothing to concatenate
What it means
concat() joins a list of clip files into one video via an ffmpeg concat demuxer invocation. It raises ValueError('nothing to concatenate') when the clips list is empty, because writing an empty concat listing and invoking ffmpeg would produce a meaningless/failed run.
Solutions
- Guard at the call site: only call concat when the clips list is non-empty, and decide what an empty result should mean for your pipeline.
- Trace why the upstream clip list is empty — check cut_take output directory and shot detection results.
- Log the number of clips before concat so empty lists surface earlier with context.
- If clips are generated by globbing, verify the glob pattern and directory actually match produced files.
- Fix any filter predicate that removed all clips unintentionally.
Example fix
// before
assemble.concat(clips, dst) # ValueError if clips == []
// after
if not clips:
raise SystemExit("no takes were cut; nothing to concatenate")
assemble.concat(clips, dst) Defensive patterns
Strategy: validation
Validate before calling
if not clips:
raise SystemExit("no clips produced upstream; skipping concat") Type guard
def has_clips(clips: list) -> bool:
return len(clips) > 0 and all(Path(c).exists() for c in clips) Try / catch
try:
assemble.concat(clips, dst)
except ValueError as exc:
if str(exc) == "nothing to concatenate":
log.warning("concat skipped: no clips")
return None Prevention
- Check the clip count after cut_take before concatenating
- Log list lengths at each pipeline stage to spot empty lists early
- Verify glob patterns match actually-produced clip files
- Decide explicitly how the pipeline should behave when zero takes are cut
- Filter predicates should warn when they remove every element
When it happens
Trigger: concat([]) called directly, or an upstream step (e.g. cut_take producing zero takes, filtered shot lists) yields an empty clips list that is passed through to concat.
Common situations: Shot detection found no shots so cut_take exported no clips; caller filtered all clips out by a predicate; path glob matched nothing; wiring bug passing the wrong (empty) list variable.
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
- merge_videos() needs at least one video URL
- nothing to concatenate
- analyze() needs at least one frame
- analyze() needs at least one frame
- at least one explicit seed is required
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/245f4da20fd4f116.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-distillation/scripts/taste/assemble.py:181
f"[0:v]format=gbrp[base];"
f"[base][ov]blend=all_mode={blend or 'screen'}:shortest=1,format=yuv420p"
)
_run([
"ffmpeg", "-nostdin", "-loglevel", "error", "-y",
# Keep the still alive until the video ends; shortest=1 otherwise
# terminates every shot after the image's single decoded frame.
"-i", str(clip), "-loop", "1", "-i", str(image), "-filter_complex", fc,
"-c:v", "libx264", "-crf", "14", "-preset", "veryfast",
"-pix_fmt", "yuv420p", "-an", str(dst),
])
return Path(dst)
def concat(clips: list[str | Path], dst: str | Path, fps: float = 24.0) -> Path:
"""Join clips into one file. Assumes they already share codec and size."""
clips = [Path(c) for c in clips]
if not clips:
raise ValueError("nothing to concatenate")
dst = Path(dst)
dst.parent.mkdir(parents=True, exist_ok=True)
listing = dst.parent / f"{dst.stem}_concat.txt"
listing.write_text("".join(f"file '{c.resolve().as_posix()}'\n" for c in clips))
_run([
"ffmpeg", "-nostdin", "-loglevel", "error", "-y",
"-f", "concat", "-safe", "0", "-i", str(listing),
"-vf", f"fps={fps:.6f}",
"-c:v", "libx264", "-crf", "16", "-pix_fmt", "yuv420p", str(dst),
])
listing.unlink(missing_ok=True)
return dst
def normalize(
src: str | Path,
dst: str | Path,
width: int,View on GitHub (pinned to 8321021c54)