affaan-m/ECC · error · ValueError
all takes must be readable local files
Error message
all takes must be readable local files
What it means
forge() validates its input media before doing any work: the takes list must be non-empty and every entry must be an existing regular file (Path(t).is_file()). If any take is missing, a directory, or the list is empty, it raises ValueError so ffprobe/ffmpeg never see a bad input.
Solutions
- Verify each take path exists with Path(t).is_file() before calling forge.
- Use absolute paths in scripts so cwd changes do not break resolution.
- Check the shell glob actually matched (e.g. ls takes/*.mov) — an unmatched glob passes the literal pattern or expands to nothing.
- Remove directory entries and broken symlinks from the takes list.
Example fix
# before
forge('noir', takes, out='edit.mp4') # one take was deleted
# after
from pathlib import Path
takes = [t for t in takes if Path(t).is_file()]
if not takes:
raise SystemExit('no valid takes')
forge('noir', takes, out='edit.mp4') Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def takes_ok(takes):
return bool(takes) and all(Path(t).is_file() for t in takes) Try / catch
try:
forge(genre, takes, out=out)
except ValueError as e:
if 'takes' in str(e):
print('check take paths:', [t for t in takes if not Path(t).is_file()])
raise Prevention
- Filter takes with Path(t).is_file() before calling forge.
- Use absolute paths so cwd changes don't break resolution.
- Confirm shell globs matched at least one file before expanding to takes.
- Exclude directories and broken symlinks from input lists.
When it happens
Trigger: Calling forge with takes=[]; a take path that does not exist (typo, wrong cwd); a take pointing to a directory instead of a file; a broken symlink counted as a take.
Common situations: Shell glob that matched nothing (takes expanded to empty); relative paths resolved from a different working directory when invoked programmatically; files moved or deleted between planning and forging.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- all overlays must be readable local files
- base video must be a readable local file
- output already exists; choose a new --out
- output must have a video suffix distinct from…
- Path does not exist
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/95c466d6e19c5e98.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/forge.py:71
root: str = "stylepacks",
base_video: str | None = None,
base_ratio: float = 0.35,
overlays: list[str] | None = None,
overlay_every: int = 4,
overlay_opacity: float = 0.3,
duration: float | None = None,
strength: float = 1.0,
grade_base: bool = True,
width: int | None = None,
height: int | None = None,
work: str = "out/forge_work",
plan: list[dict] | None = None,
fps: float | None = None,
) -> Path:
out_path = Path(out)
validate_output(out_path)
if not takes or any(not Path(t).is_file() for t in takes):
raise ValueError("all takes must be readable local files")
if base_video and not Path(base_video).is_file():
raise ValueError("base video must be a readable local file")
if any(not Path(o).is_file() for o in (overlays or [])):
raise ValueError("all overlays must be readable local files")
if fps is not None and (not math.isfinite(fps) or fps <= 0):
raise ValueError("fps must be finite and positive")
sp = pack_mod.load(genre, root=root)
tgt = grade_mod.load_stats(sp.grade_path)
cad = cad_mod.load(sp.cadence_path)
# Geometry comes from the first take unless overridden; everything else is
# normalized to it so concat does not silently fail on a size mismatch.
info0 = frame_mod.probe(takes[0])
W = width or info0.width
H = height or info0.height
FPS = fps if fps is not None else info0.fps
if not math.isfinite(FPS) or FPS <= 0:
raise ValueError("source fps must be finite and positive; provide --fps")View on GitHub (pinned to 8321021c54)