GyulyVGC/sniffnet · error · SystemExit

Refusing to overwrite an existing release in

Error message

Refusing to overwrite an existing release in {output}; use --output with a fresh directory

What it means

prepare() refuses to build a Debian source release into an --output directory that already exists and contains files. This guard prevents silently mixing a new release with stale artifacts from a previous run (or clobbering files the user wants kept). It aborts before any staging work so no partial output is written.

Solutions

  1. Delete or empty the output directory (rm -rf target/debian-source) and re-run
  2. Pass --output with a fresh, non-existent or empty directory path
  3. If the previous run's artifacts are wanted, move them aside before re-running

Example fix

// before
python3 prepare.py
# after
rm -rf target/debian-source && python3 prepare.py
# or
python3 prepare.py --output /tmp/deb-out-v1.3.1
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
output = Path(args.output).resolve()
if output.exists() and any(output.iterdir()):
    raise SystemExit(f"Output directory {output} is not empty; choose a fresh --output")

Type guard

def is_fresh_output_dir(p: Path) -> bool:
    return not p.exists() or not any(p.iterdir())

Try / catch

try:
    prepare(output)
except SystemExit as e:
    print(f"Packaging aborted: {e}", file=sys.stderr)
    sys.exit(2)

Prevention

When it happens

Trigger: Running prepare.py with --output pointing at a directory that exists and is non-empty; most commonly re-running the script with the same (default target/debian-source) output directory after a previous successful or partial run.

Common situations: Re-running the packager after a failed build left artifacts behind; running twice for the same version; pointing --output at a shared or pre-created release directory; forgetting that the default output dir persists between runs.

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.


AI-assisted analysis of GyulyVGC/sniffnet@592a62a5ad (2026-09-18). Data as JSON: /api/errors/39221c168c4c85d8. Report an issue: GitHub.

Appendix: source

Thrown at resources/packaging/linux/deb-source/prepare.py:28

import shutil
import subprocess
import sys
import tarfile
import tempfile
import tomllib


ROOT = Path(__file__).resolve().parents[4]
DEBIAN = Path(__file__).resolve().parent / "debian"


def run(*args, cwd=ROOT, **kwargs):
    return subprocess.run(args, cwd=cwd, check=True, **kwargs)


def prepare(output):
    if output.exists() and any(output.iterdir()):
        raise SystemExit(f"Refusing to overwrite an existing release in {output}; use --output with a fresh directory")
    # Stage outside the checkout so Cargo cannot inherit a newer parent workspace.
    with tempfile.TemporaryDirectory(prefix="sniffnet-debian-") as staging:
        source = prepare_staged(Path(staging))
        output.mkdir(parents=True, exist_ok=True)
        for path in Path(staging).iterdir():
            shutil.move(str(path), output / path.name)
    print(f"Release files: {output}", flush=True)
    return output / source.name


def prepare_staged(output):
    changelog = (DEBIAN / "changelog").read_text()
    match = re.match(r"sniffnet \(([^)]+)\) ([\w-]+);", changelog)
    if not match:
        raise SystemExit("Cannot parse debian/changelog")
    version = match[1].rsplit("-", 1)[0]
    tag = f"refs/tags/v{version}"
    commit = run("git", "rev-parse", "--verify", f"{tag}^{{commit}}",

View on GitHub (pinned to 592a62a5ad)