nexu-io/open-design · error · SystemExit
{run_dir} already exists and is not empty; pass --force to r
Error message
{run_dir} already exists and is not empty; pass --force to reuse it What it means
Raised by prepare_pet_run.py when the resolved run directory already exists and contains at least one entry, and --force was not passed. It is a deliberate guard so an in-progress or previously-generated pet run is never silently overwritten. The script resolves run_dir from --output-dir (or default_output_dir(pet_id)) and treats any non-empty target as occupied.
Source
Thrown at skills/hatch-pet/scripts/prepare_pet_run.py:582
raw_reference_paths = [
Path(raw_path).expanduser().resolve() for raw_path in args.reference
]
args.display_name = infer_name(args, raw_reference_paths)
args.pet_name = (args.pet_name or args.display_name).strip()
args.description = infer_description(args, raw_reference_paths)
args.pet_notes = infer_pet_notes(args, raw_reference_paths)
args.pet_id = slugify(args.pet_id or args.pet_name or args.display_name)
if not args.pet_id:
raise SystemExit("pet id must contain at least one letter or digit")
run_dir = (
Path(args.output_dir).expanduser().resolve()
if args.output_dir
else default_output_dir(args.pet_id).resolve()
)
if run_dir.exists() and any(run_dir.iterdir()) and not args.force:
raise SystemExit(
f"{run_dir} already exists and is not empty; pass --force to reuse it"
)
run_dir.mkdir(parents=True, exist_ok=True)
ref_dir = run_dir / "references"
prompt_dir = run_dir / "prompts"
row_prompt_dir = prompt_dir / "rows"
for directory in [
ref_dir,
prompt_dir,
row_prompt_dir,
run_dir / "decoded",
run_dir / "qa",
]:
directory.mkdir(parents=True, exist_ok=True)
copied_refs: list[dict[str, object]] = []
copied_ref_paths: list[Path] = []View on GitHub (pinned to 5be4028344)
Solutions
- Pass --force if you intentionally want to reuse the existing run_dir.
- Move or delete the existing run_dir before re-running, e.g. rm -rf <run_dir>.
- Use a distinct --pet-id (which changes default_output_dir) or a fresh --output-dir for the new attempt.
- If the directory is unexpectedly non-empty (leftover dotfiles), inspect run_dir.iterdir() and clean the stray entries.
Example fix
# before python skills/hatch-pet/scripts/prepare_pet_run.py --pet-name "Fenrir" # after (reuse intentionally) python skills/hatch-pet/scripts/prepare_pet_run.py --pet-name "Fenrir" --force
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
run_dir = Path(args.output_dir or default_output_dir(args.pet_id)).expanduser().resolve()
if run_dir.exists() and any(run_dir.iterdir()) and not args.force:
print(f"refusing to overwrite {run_dir}; pass --force or pick a new --output-dir")
raise SystemExit(2) Prevention
- Always pass an explicit --output-dir for CI runs so default_output_dir collisions cannot happen.
- Treat run_dir as disposable: clean it before re-preparing instead of relying on --force.
- If --force is needed often, wrap the script in a make target that wipes the run_dir first.
When it happens
Trigger: Running prepare_pet_run.py a second time with the same --pet-id (same default_output_dir), or pointing --output-dir at a folder that already holds files; re-running after a partial/failed generation without cleaning up.
Common situations: Iterating on a pet design and forgetting the previous run is still on disk; CI/local rerun after a crash left the run_dir partially populated; two teammates sharing a workspace whose default output root collides.
Related errors
- {output} already exists; pass --force to replace it
- reference not found: {source}
- file not found: {path}
- row prompt not found: {prompt_path}
- job manifest not found: {path}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/0a82b266ad8e32e9.
Report an issue: GitHub.