affaan-m/ECC · error · ValueError
Crop must contain four finite values
Error message
Crop must contain four finite values
What it means
filter_graph() validates the start and end camera-crop rectangles used for the animated zoompan. Each crop must be a sequence of exactly four finite numbers; it raises ValueError('Crop must contain four finite values') otherwise. A second check ensures each rect fits within normalized [0,1] coordinates.
Solutions
- Pass exactly four numbers [x, y, w, h] for both start and end crops
- Validate length and finiteness before calling: len(c) == 4 and all(math.isfinite(v) for v in c)
- Fix the config/data source producing short or NaN crop lists
- Check argument order — start and end are both crop rectangles, not timestamps
Example fix
// before make_clip(src, start=[0.1, 0.1, 0.5], end=[0, 0, 1, 1], ...) # only 3 values // after make_clip(src, start=[0.1, 0.1, 0.5, 0.5], end=[0, 0, 1, 1], ...)
Defensive patterns
Strategy: validation
Validate before calling
import math
def valid_crop(c):
return (isinstance(c, (list, tuple)) and len(c) == 4
and all(isinstance(v, (int, float)) and math.isfinite(v) for v in c))
assert valid_crop(start_crop) and valid_crop(end_crop) Type guard
def is_valid_crop(c) -> bool:
return (isinstance(c, (list, tuple)) and len(c) == 4
and all(isinstance(v, (int, float)) and not isinstance(v, bool) and math.isfinite(v) for v in c)) Try / catch
try:
make_clip(src, start=start_crop, end=end_crop, output=out)
except ValueError as e:
if 'Crop must contain four finite values' in str(e):
start_crop, end_crop = [0, 0, 1, 1], [0, 0, 1, 1] # safe full-frame default Prevention
- Schema-validate crop config (4 finite numbers, within [0,1]) at load time
- Guard divisions that compute crops to avoid NaN
- Keep crop values in normalized [0,1] coordinates with w,h > 0
- Sanity-check argument order: start and end are both crop rectangles, not timestamps
When it happens
Trigger: Passing start/end crops with fewer or more than 4 elements (e.g. [x, y, w]); passing NaN or inf values from unparsed config; passing None or a non-iterable as start.
Common situations: Loading crop values from JSON/YAML where a key is missing so the list is short; computing crops with a division that produced NaN (0/0); swapping argument order so a scalar is passed where a 4-tuple is expected.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- apply_local needs at least one media clip
- asset contains too few frames
- asset requires verified alpha
- candidate fps/duration/retime ambiguity
- FileNotFoundError(source)
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/a0056d1536541f38.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/media/stills.py:14
"""Animate an image between normalized crop rectangles using local FFmpeg."""
import argparse
import math
import subprocess
from pathlib import Path
from .common import geometry, output_file
def filter_graph(start, end, frames, width, height, fps):
for crop in (start, end):
if len(crop) != 4 or any(not math.isfinite(v) for v in crop):
raise ValueError("Crop must contain four finite values")
x, y, w, h = crop
if min(x, y) < 0 or min(w, h) <= 0 or x + w > 1 or y + h > 1:
raise ValueError("Crop must fit within normalized image coordinates")
# Coordinates refer to the image after scale-cover to output aspect.
# Expand each requested rectangle to output aspect, then interpolate its
# width and center; zoompan clamps the window at image boundaries.
fraction = f"on/{max(1, frames - 1)}"
def interpolate(a, b):
return f"({a}+({b}-{a})*{fraction})"
zoom = f"1/{interpolate(max(start[2], start[3]), max(end[2], end[3]))}"
cx = interpolate(start[0] + start[2] / 2, end[0] + end[2] / 2)
cy = interpolate(start[1] + start[3] / 2, end[1] + end[3] / 2)
return (
f"scale={width * 2}:{height * 2}:force_original_aspect_ratio=increase,"
f"crop={width * 2}:{height * 2},zoompan=z='{zoom}':"
f"x='iw*{cx}-iw/zoom/2':y='ih*{cy}-ih/zoom/2':"View on GitHub (pinned to 8321021c54)