invoke-ai/InvokeAI · error · FileNotFoundError

Unable to open video at {video_path}

Error message

Unable to open video at {video_path}

What it means

_probe opens the video with cv2.VideoCapture to read metadata. If the capture cannot be opened, it releases the handle and raises FileNotFoundError naming the path. Note it is a FileNotFoundError even when the file exists but is unreadable as video by OpenCV.

Source

Thrown at invokeai/app/util/video_decode_worker.py:156

        duration = float(meta.get("duration", 0.0)) if meta.get("duration") is not None else 0.0
        size = meta.get("size")
        if size is None:
            # Fall through to cv2 — imageio didn't give us dimensions.
            raise ValueError("imageio probe missing 'size'")
        width, height = int(size[0]), int(size[1])
        fps: Optional[float] = float(fps_raw) if fps_raw and fps_raw > 0 else None
        codec_raw = meta.get("codec")
        codec = str(codec_raw).lower() if codec_raw else None
        return width, height, duration, fps, codec
    except Exception:
        pass

    import cv2

    capture = cv2.VideoCapture(str(video_path))
    if not capture.isOpened():
        capture.release()
        raise FileNotFoundError(f"Unable to open video at {video_path}")
    try:
        width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH))
        height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
        frame_count = int(capture.get(cv2.CAP_PROP_FRAME_COUNT))
        fps_raw = capture.get(cv2.CAP_PROP_FPS)
        fps_v2: Optional[float] = float(fps_raw) if fps_raw and fps_raw > 0 else None
        duration = (frame_count / fps_v2) if (fps_v2 and frame_count > 0) else 0.0
        fourcc = int(capture.get(cv2.CAP_PROP_FOURCC))
        codec = "".join(chr((fourcc >> (8 * index)) & 0xFF) for index in range(4)).strip().lower() or None
    finally:
        capture.release()
    return width, height, duration, fps_v2, codec


def _count(video_path: Path) -> Optional[int]:
    """Return the exact decoded frame count, or None if neither backend can determine it.

    Tries imageio's improps first (works for a handful of codecs that expose nframes in

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Check os.path.exists() and permissions on the path first
  2. Run ffprobe <path> to confirm OpenCV/FFmpeg can read the container and codec
  3. Reinstall/rebuild opencv-python (pip install --force-reinstall opencv-python) if video I/O backends are missing
  4. Re-encode with ffmpeg to a standard codec (h264 mp4)

Example fix

// before
_probe(Path("missing.mp4"))

// after
p = Path("missing.mp4")
if not p.exists() or not p.is_file():
    raise FileNotFoundError(f"Video file not found: {p}")
_probe(p)
Defensive patterns

Strategy: try-catch

Validate before calling

from pathlib import Path
def openable(path) -> bool:
    p = Path(path)
    return p.exists() and p.is_file() and p.stat().st_size > 0 and os.access(p, os.R_OK)

Try / catch

try:
    _probe(video_path)
except FileNotFoundError as e:
    logger.error("cannot open video: %s", e)
    # skip / re-encode / surface user error

Prevention

When it happens

Trigger: Calling _probe (directly or via _assert_decodable_dims/main) on a nonexistent path, a path without read permission, an unsupported/corrupt container, or a codec the bundled OpenCV FFmpeg can't demux.

Common situations: Wrong path or typo; file deleted between listing and probing; proprietary codecs (e.g. some HEVC/ProRes variants) missing from the FFmpeg build; OpenCV built without FFmpeg video I/O support.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/cc30dcabd4f3ce0b. Report an issue: GitHub.