{"record":{"id":"1272a5a3b2fdec53","repo":"affaan-m/ECC","slug":"filenotfounderror-source-stills","errorCode":null,"errorMessage":"FileNotFoundError(source)","messagePattern":"FileNotFoundError\\(source\\)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/media/stills.py","lineNumber":54,"sourceCode":"\ndef make_clip(\n    source,\n    output,\n    duration=4,\n    start_crop=(0, 0, 1, 1),\n    end_crop=(0.1, 0.1, 0.8, 0.8),\n    width=1920,\n    height=1080,\n    fps=30,\n    overwrite=False,\n    runner=subprocess.run,\n):\n    geometry(width, height, fps, duration)\n    graph = filter_graph(\n        start_crop, end_crop, max(1, round(duration * fps)), width, height, fps\n    )\n    if not Path(source).is_file():\n        raise FileNotFoundError(source)\n    if Path(source).resolve() == Path(output).resolve():\n        raise ValueError(\"Output must differ from the original source media\")\n    with output_file(output, overwrite) as temporary:\n        runner(\n            [\n                \"ffmpeg\",\n                \"-nostdin\",\n                \"-y\",\n                \"-v\",\n                \"error\",\n                \"-i\",\n                str(source),\n                \"-vf\",\n                graph,\n                \"-an\",\n                \"-t\",\n                str(duration),\n                \"-c:v\",","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/media/stills.py#L36-L72","documentation":"make_clip verifies the source media file exists before spawning ffmpeg, raising FileNotFoundError with the source path if it does not. This is a fail-fast guard so ffmpeg never runs against a missing input.","triggerScenarios":"Calling make_clip(source=<path>) where Path(source).is_file() is False — a typo in the filename, a relative path resolved from the wrong working directory, or a file deleted between selection and clip creation.","commonSituations":"Running the script from a different cwd than expected; passing a directory instead of a file; stale paths from a config file after files were moved; Windows/POSIX path separator mistakes.","solutions":["Check the path with Path(source).is_file() before calling make_clip and print the absolute path to debug","Convert to an absolute path (Path(source).resolve()) and verify it points at the intended file","Pass a directory-absolute path in your config or CLI invocation rather than a cwd-relative one"],"exampleFix":"// before\nmake_clip(\"assets/hero.jpg\", \"out.mp4\", ...)  # relative to wrong cwd\n// after\nfrom pathlib import Path\nsrc = Path(\"assets/hero.jpg\").resolve()\nassert src.is_file(), f\"missing source: {src}\"\nmake_clip(str(src), \"out.mp4\", ...)","handlingStrategy":"validation","validationCode":"from pathlib import Path\nsrc = Path(source)\nif not src.is_file():\n    raise SystemExit(f\"source media not found: {src.resolve()}\")","typeGuard":null,"tryCatchPattern":"try:\n    make_clip(source, output, ...)\nexcept FileNotFoundError as e:\n    print(f\"Source media missing: {e}\")","preventionTips":["Always resolve paths to absolute before passing them in","Log Path(source).resolve() when debugging missing files","Verify inputs exist in a preflight step before batch jobs"],"tags":["filesystem","file-not-found","ffmpeg","paths"],"backgroundTag":"file-not-found","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"}