affaan-m/ECC · error · ValueError

base video must be a readable local file

Error message

base video must be a readable local file

What it means

forge() checks the optional base_video the same way as takes: when a base video is supplied it must be an existing regular file. A missing, mistyped, or non-file base path raises ValueError before any media processing starts.

Solutions

  1. Confirm the base video path exists and is a file: Path(base_video).is_file().
  2. Download/copy remote base assets locally first — forge only accepts local files.
  3. Fix typos or re-mount the volume holding the base clip.
  4. Omit base_video if you did not intend to composite over a base clip (only non-empty values are checked).

Example fix

# before
forge('noir', takes, base_video='b-roll/bg.mp4', out='edit.mp4')

# after
from pathlib import Path
base = Path('b-roll/bg.mp4')
if base.is_file():
    forge('noir', takes, base_video=str(base), out='edit.mp4')
else:
    forge('noir', takes, out='edit.mp4')
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def base_ok(base_video):
    return not base_video or Path(base_video).is_file()

Try / catch

try:
    forge(genre, takes, base_video=base_video, out=out)
except ValueError as e:
    if 'base video' in str(e):
        print(f'base video missing: {base_video}')
    raise

Prevention

When it happens

Trigger: Passing base_video='footage/bg.mp4' where the file does not exist; pointing base_video at a directory; passing a URL instead of a local path (is_file() is False for remote paths).

Common situations: Base clip stored on an external drive not mounted; moving the project without moving the base video; confusing a remote asset URL with a local file requirement.

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


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

Appendix: source

Thrown at skills/taste-application/scripts/forge.py:73

    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")
    if W <= 0 or H <= 0:
        raise ValueError("output width and height must be positive")

View on GitHub (pinned to 8321021c54)