{"record":{"id":"ab8106d59e3e3c35","repo":"affaan-m/ECC","slug":"output-must-differ-from-the-original-source-media-stills","errorCode":null,"errorMessage":"Output must differ from the original source media","messagePattern":"Output must differ from the original source media","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/media/stills.py","lineNumber":56,"sourceCode":"    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\",\n                \"libx264\",\n                \"-preset\",","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/media/stills.py#L38-L74","documentation":"make_clip refuses to run when the resolved output path equals the resolved source path, because writing the generated clip would destroy the original media. The comparison uses Path.resolve() so symlinks and relative/absolute spellings of the same file are caught.","triggerScenarios":"Calling make_clip(source=\"clip.mp4\", output=\"clip.mp4\"), or output=\"./clip.mp4\" while source is an absolute path to the same file, or output given via a symlink that resolves to the source.","commonSituations":"Scripting batch conversions where in/out are built from the same variable; defaulting output to the input filename in a template; users pointing --output at the source directory with the same basename.","solutions":["Choose a distinct output filename or directory for the generated clip","Resolve both paths in your script and assert they differ before calling make_clip","If in-place conversion is intended, copy the source to a temp file and use the copy as source"],"exampleFix":"// before\nmake_clip(\"video.mp4\", \"video.mp4\")  # would overwrite source\n// after\nmake_clip(\"video.mp4\", \"video_zoom.mp4\")","handlingStrategy":"validation","validationCode":"from pathlib import Path\nif Path(source).resolve() == Path(output).resolve():\n    raise SystemExit(\"output must differ from source\")","typeGuard":null,"tryCatchPattern":"try:\n    make_clip(source, output, ...)\nexcept ValueError as e:\n    if \"must differ\" in str(e):\n        output = Path(output).with_stem(Path(output).stem + \"_clip\")\n        make_clip(source, str(output), ...)","preventionTips":["Derive output names programmatically (stem + suffix) instead of reusing the input variable","Never point --output at the same file as the source in scripts","Keep generated artifacts in a separate output directory"],"tags":["filesystem","safety","destructive-operation","paths"],"backgroundTag":"file-already-exists","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"}