affaan-m/ECC · error · SystemExit

every shot failed; nothing to compose

Error message

every shot failed; nothing to compose

What it means

Aggregate failure guard in apply(): every shot generation in the worker pool failed, leaving no takes to compose into the rough cut. Individual shot errors were already logged; this fires only when the result set is empty.

Solutions

  1. Inspect the per-shot errors logged above this message (API auth, rate limit, or provider outage are typical)
  2. Fix credentials/network and re-run with a new --out
  3. Run with --dry-run first to validate the pipeline without spend
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at skills/taste-application/scripts/apply.py:409 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/6bede9786c77836c. Report an issue: GitHub.

Appendix: source

Thrown at skills/taste-application/scripts/apply.py:409

            raise SystemExit("--overlay not found: " + ", ".join(str(m) for m in missing))
        for o in overlays:
            overlay_urls.append(falapi.upload(Path(o)))
        print(f"  overlays       : {len(overlay_urls)}")

    # Uploads are cached by (path, mtime, size), so the workers racing on the
    # same handful of stills still only pay for each upload once.
    lock = threading.Lock()
    workers = max(1, min(int(concurrency), len(shots)))
    print(f"  generating     : {len(shots)} shot(s), {workers} worker(s) ...")
    with ThreadPoolExecutor(max_workers=workers) as pool:
        list(pool.map(lambda s: _generate(s, base_video_url, lock), shots))

    ok = [s for s in shots if s.video_url]
    failed = [s for s in shots if not s.video_url]
    for s in failed:
        print(f"  !! shot {s.index} failed: {s.error}", file=sys.stderr)
    if not ok:
        raise SystemExit("every shot failed; nothing to compose")

    # Close ranks over any failed shot so the cut has no black hole in it.
    timeline_clock = 0.0
    for s in ok:
        s.timeline_start = timeline_clock
        timeline_clock += s.duration

    # Generate long, trim short. Video models quantize to whole seconds with a
    # floor of a few, but the pack's cadence is often faster than that (a 1.1s
    # shot is normal in a fast reference). So each shot is requested at the
    # model's nearest legal length and then cut back to its cadence-derived
    # duration on the timeline - which is the only way the rough cut actually
    # inherits the reference's rhythm instead of a 3s-per-clip floor.
    tracks = [
        {
            "id": "shots",
            "type": "video",
            "keyframes": [

View on GitHub (pinned to 8321021c54)