{"record":{"id":"1d4a5bd5d92041ab","repo":"affaan-m/ECC","slug":"invalid-fps","errorCode":null,"errorMessage":"invalid fps","messagePattern":"invalid fps","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/resolve.py","lineNumber":36,"sourceCode":"from .timeline import fps_fraction\n\n\ndef _integer(value, label, minimum=0):\n    if isinstance(value, bool) or not isinstance(value, int) or value < minimum:\n        raise ValueError(f\"{label} must be an integer >= {minimum}\")\n    return value\n\n\ndef _fps(value):\n    if isinstance(value, bool):\n        raise ValueError(\"fps must be finite and positive\")\n    try:\n        number = float(Fraction(str(value)))\n        if not math.isfinite(number) or number <= 0:\n            raise ValueError(\"fps must be finite and positive\")\n        return fps_fraction(number)\n    except (TypeError, ZeroDivisionError, OverflowError) as exc:\n        raise ValueError(\"invalid fps\") from exc\n\n\ndef probe_asset(path):\n    \"\"\"Count decoded video frames; never infer source length from duration.\"\"\"\n    result = subprocess.run(\n        [\n            \"ffprobe\",\n            \"-v\",\n            \"error\",\n            \"-select_streams\",\n            \"v:0\",\n            \"-count_frames\",\n            \"-show_entries\",\n            \"stream=avg_frame_rate,r_frame_rate,nb_read_frames,pix_fmt\",\n            \"-of\",\n            \"json\",\n            str(path),\n        ],","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/resolve.py#L18-L54","documentation":"This is the ValueError('invalid fps') raised from _fps's except clause when converting the value via float(Fraction(str(value))) fails with TypeError, ZeroDivisionError, or OverflowError. It means the fps value's string form could not be interpreted as a rational/decimal number at all (e.g. a rational with zero denominator, or a non-numeric type).","triggerScenarios":"Passing fps values whose str() is not a parseable rational: Fraction('1/0') raising ZeroDivisionError, an object whose str() is non-numeric raising ValueError→TypeError path, or an absurdly large value raising OverflowError on float().","commonSituations":"Rational strings with zero denominator from malformed ffprobe data ('0/0' denominator path handled elsewhere, '5/0' here); passing a dict or list as fps; extremely large numbers exceeding float range.","solutions":["Inspect the exact fps value being passed and confirm str(value) parses as a rational (e.g. '30', '29.97', '30000/1001')","Never pass rationals with zero denominator; sanitize or reject 'N/0' inputs before calling","Pass plain numbers (30, 29.97) instead of exotic objects so str() conversion is safe","Catch this ValueError at the call site and surface which placement/config supplied the bad fps"],"exampleFix":"# before\nfps = stream_metadata['rate']  # '5/0'\nresolve.allocate_placements(plan, placements, fps=fps)\n# after\nnum, den = (int(x) for x in stream_metadata['rate'].split('/'))\nif den == 0:\n    raise ValueError(f'bad frame rate in source metadata: {stream_metadata[\"rate\"]}')\nresolve.allocate_placements(plan, placements, fps=f'{num}/{den}')","handlingStrategy":"validation","validationCode":"from fractions import Fraction\n\ndef parse_fps(value):\n    try:\n        return float(Fraction(str(value)))\n    except (ValueError, ZeroDivisionError, OverflowError, TypeError):\n        return None\n\nassert parse_fps('30000/1001') is not None","typeGuard":null,"tryCatchPattern":"try:\n    resolve.plan(placements, fps=raw_fps)\nexcept ValueError as e:\n    if str(e) == 'invalid fps':\n        raise ConfigError(f'cannot parse fps: {raw_fps!r}') from e\n    raise","preventionTips":["Reject rationals with zero denominator before passing them on","Log repr(raw_fps) on failure to see the offending value","Prefer passing plain floats/integers over exotic objects"],"tags":["validation","fps","parsing"],"backgroundTag":"invalid-argument-format","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"}