affaan-m/ECC · error · SystemExit

--overlay not found

Error message

--overlay not found: {missing paths}

What it means

Pre-flight check in apply.py for --overlay paths: it deliberately fails before any paid upload because forge() would only reject a missing overlay later, stranding every generated take without a manifest. One or more overlay paths do not exist.

Solutions

  1. Fix or remove the missing overlay paths listed in the message
  2. Verify each --overlay argument resolves to an existing file
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at skills/taste-application/scripts/apply.py:391 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/abce4b3528aa80b5. Report an issue: GitHub.

Appendix: source

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

        )
        shots.append(s)
        clock += float(t["used"])

    base_video_url = None
    if base_video:
        bp = Path(base_video)
        if not bp.exists():
            raise SystemExit(f"--base-video not found: {bp}")
        base_video_url = falapi.upload(bp)
        print(f"  base video     : {bp.name} (frames pulled per shot timecode)")

    overlay_urls: list[str] = []
    if overlays:
        # Fail before any paid upload: forge() rejects a missing overlay
        # later, which would strand every generated take without a manifest.
        missing = [Path(o) for o in overlays if not Path(o).is_file()]
        if missing:
            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")

View on GitHub (pinned to 8321021c54)