affaan-m/ECC · error · ValueError
Geometry, fps and duration must be finite and positive
Error message
Geometry, fps and duration must be finite and positive
What it means
geometry() validates that width, height, fps, and duration are all real, finite, positive numbers before any rendering or draft creation proceeds. Booleans are explicitly rejected even though bool subclasses int. This is the first line of defense against nonsense output dimensions or timings.
Solutions
- Coerce CLI/config values to float/int before calling: width = int(width)
- Validate the values are finite and > 0 in your caller before invoking the library
- Fix the probe/duration computation returning 0 or NaN
- Use None-checks on optional config so None never reaches geometry()
Example fix
// before make_clip(src, width='1920', height=1080, fps=30) // after make_clip(src, width=int(width_arg), height=1080, fps=30, duration=float(dur))
Defensive patterns
Strategy: validation
Validate before calling
def geometry_args_ok(width, height, fps, duration=1):
values = (width, height, fps, duration)
return all(
isinstance(v, (int, float)) and not isinstance(v, bool)
and math.isfinite(v) and v > 0
for v in values
) Type guard
def is_positive_number(v):
return isinstance(v, (int, float)) and not isinstance(v, bool) and math.isfinite(v) and v > 0 Try / catch
try:
export_draft(files, name=name, width=w, height=h, fps=fps)
except ValueError as e:
if 'finite and positive' in str(e):
raise SystemExit(f'bad geometry args: w={w!r} h={h!r} fps={fps!r}') Prevention
- Parse CLI/config numbers with int()/float() before passing them
- Reject None/0/negative at the config-loading boundary
- Compute durations with guarded math that cannot yield NaN or 0
- Never pass booleans where numbers are expected
When it happens
Trigger: Passing width/height/fps/duration as None, NaN, inf, 0, negative numbers, True/False, or non-numeric strings into export_draft, render, or make_clip.
Common situations: Unparsed CLI arguments arriving as strings ('1920'); division results producing NaN; config defaults left at 0 or None; a duration computed as 0 from a failed probe; JSON configs where numbers came through as booleans.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- contains a non-finite numeric value
- has an invalid finite source duration
- is outside its source duration
- application bundle differs from its bound evidence
- At least one video is required
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/96d27da459f76df2.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/media/common.py:13
"""Validation and transactional output for local media tools."""
import math
import os
import tempfile
from contextlib import contextmanager
from pathlib import Path
def geometry(width, height, fps, duration=1):
for value in (width, height, fps, duration):
if isinstance(value, bool) or not math.isfinite(value) or value <= 0:
raise ValueError("Geometry, fps and duration must be finite and positive")
if width != int(width) or height != int(height) or width % 2 or height % 2:
raise ValueError("Width and height must be even integers")
@contextmanager
def output_file(destination, overwrite=False):
destination = Path(destination)
if os.path.lexists(destination) and not overwrite:
raise FileExistsError(destination)
destination.parent.mkdir(parents=True, exist_ok=True)
fd, filename = tempfile.mkstemp(
prefix=".media-", suffix=destination.suffix, dir=destination.parent
)
os.close(fd)
temporary = Path(filename)
try:
yield temporary
if temporary.stat().st_size == 0:View on GitHub (pinned to 8321021c54)