{"record":{"id":"96d27da459f76df2","repo":"affaan-m/ECC","slug":"geometry-fps-and-duration-must-be-finite-and-positive","errorCode":null,"errorMessage":"Geometry, fps and duration must be finite and positive","messagePattern":"Geometry, fps and duration must be finite and positive","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/media/common.py","lineNumber":13,"sourceCode":"\"\"\"Validation and transactional output for local media tools.\"\"\"\n\nimport math\nimport os\nimport tempfile\nfrom contextlib import contextmanager\nfrom pathlib import Path\n\n\ndef geometry(width, height, fps, duration=1):\n    for value in (width, height, fps, duration):\n        if isinstance(value, bool) or not math.isfinite(value) or value <= 0:\n            raise ValueError(\"Geometry, fps and duration must be finite and positive\")\n    if width != int(width) or height != int(height) or width % 2 or height % 2:\n        raise ValueError(\"Width and height must be even integers\")\n\n\n@contextmanager\ndef output_file(destination, overwrite=False):\n    destination = Path(destination)\n    if os.path.lexists(destination) and not overwrite:\n        raise FileExistsError(destination)\n    destination.parent.mkdir(parents=True, exist_ok=True)\n    fd, filename = tempfile.mkstemp(\n        prefix=\".media-\", suffix=destination.suffix, dir=destination.parent\n    )\n    os.close(fd)\n    temporary = Path(filename)\n    try:\n        yield temporary\n        if temporary.stat().st_size == 0:","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/media/common.py#L1-L31","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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()"],"exampleFix":"// before\nmake_clip(src, width='1920', height=1080, fps=30)\n\n// after\nmake_clip(src, width=int(width_arg), height=1080, fps=30, duration=float(dur))","handlingStrategy":"validation","validationCode":"def geometry_args_ok(width, height, fps, duration=1):\n    values = (width, height, fps, duration)\n    return all(\n        isinstance(v, (int, float)) and not isinstance(v, bool)\n        and math.isfinite(v) and v > 0\n        for v in values\n    )","typeGuard":"def is_positive_number(v):\n    return isinstance(v, (int, float)) and not isinstance(v, bool) and math.isfinite(v) and v > 0","tryCatchPattern":"try:\n    export_draft(files, name=name, width=w, height=h, fps=fps)\nexcept ValueError as e:\n    if 'finite and positive' in str(e):\n        raise SystemExit(f'bad geometry args: w={w!r} h={h!r} fps={fps!r}')","preventionTips":["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"],"tags":["python","geometry","validation","numeric"],"backgroundTag":"invalid-argument-value","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}