affaan-m/ECC · error · FileExistsError

FileExistsError(destination)

Error message

FileExistsError(destination)

What it means

output_file is a context manager that safely writes media to a destination path via a temporary file. It raises FileExistsError when the destination path already exists (or is a dangling symlink) and the caller did not pass overwrite=True. This prevents accidentally destroying existing media files.

Solutions

  1. Delete or move the existing file at the destination path before re-running
  2. Pass overwrite=True to the render/make_clip call (it forwards to output_file) to replace the existing file atomically via os.replace
  3. Choose a different output filename

Example fix

// before
render(src, start, output='out.mp4')  # out.mp4 exists -> FileExistsError
// after
render(src, start, output='out.mp4', overwrite=True)
Defensive patterns

Strategy: try-catch

Validate before calling

from pathlib import Path
import os
if os.path.lexists(out_path) and not overwrite:
    raise FileExistsError(out_path)  # or handle before calling

Try / catch

try:
    render(src, start, output=out_path)
except FileExistsError:
    render(src, start, output=out_path, overwrite=True)  # or pick a new name

Prevention

When it happens

Trigger: Calling render() or make_clip() with an output path that already exists on disk without overwrite=True; the destination being a broken symlink caught by os.path.lexists.

Common situations: Re-running a render pipeline that wrote to the same output filename previously; forgetting to pass overwrite=True when intentionally replacing an old clip; stale output left over from a previous failed run.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/2ce5c5ba9fdf1340. Report an issue: GitHub.

Appendix: source

Thrown at skills/taste-application/scripts/tasteforge/media/common.py:22

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:
            os.replace(temporary, destination)
        else:
            os.link(temporary, destination)
    finally:
        temporary.unlink(missing_ok=True)

View on GitHub (pinned to 8321021c54)