affaan-m/ECC · error · ValueError
Width and height must be even integers
Error message
Width and height must be even integers
What it means
After the finiteness check, geometry() requires width and height to be whole numbers (width == int(width), height == int(height)) and even (divisible by 2), because most video codecs require even frame dimensions. Fractional or odd dimensions abort the export/render.
Solutions
- Round down to an even number: height = int(height) // 2 * 2
- Use standard even presets (1920x1080, 1280x720, 1080x1920)
- Apply even-rounding after any aspect-ratio computation before calling the API
- Reject odd user-supplied dimensions in your UI/config layer
Example fix
// before height = width / aspect # e.g. 815.999... export_draft(files, name='edit', width=1920, height=height) // after height = int(width / aspect) // 2 * 2 # even integer export_draft(files, name='edit', width=1920, height=height)
Defensive patterns
Strategy: validation
Validate before calling
def dims_even(width, height):
return width == int(width) and height == int(height) and width % 2 == 0 and height % 2 == 0
# normalize first
width, height = int(width), int(height) // 2 * 2
assert dims_even(width, height) Type guard
def is_even_int_dimension(v):
return isinstance(v, int) and not isinstance(v, bool) and v > 0 and v % 2 == 0 Try / catch
try:
render(src, width=w, height=h)
except ValueError as e:
if 'even integers' in str(e):
render(src, width=w - w % 2, height=h - h % 2) Prevention
- Centralize dimension normalization: even-round every computed size
- Snap to standard presets (1280x720, 1920x1080) when possible
- Apply int() before even-rounding to remove float drift
- Validate dimension configs at load time with the guard above
When it happens
Trigger: Calling export_draft/render/make_clip with width=1080.5, height=721, or any non-integral float; computing dimensions from an aspect-ratio calculation without rounding to even values.
Common situations: Aspect-ratio math like int(1920/2.35) yielding an odd height; passing heights like 719 or 1081 from UI presets; scaling code producing floats (1920 * 0.577).
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Geometry, fps and duration must be finite and positive
- output width and height must be positive
- analyze() needs at least one frame
- analyze() needs at least one frame
- application bundle differs from its bound evidence
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/317e6c62df1177f7.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/media/common.py:15
"""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:
raise RuntimeError("Media command produced an empty output")
if overwrite:View on GitHub (pinned to 8321021c54)