nexu-io/open-design · warning · SystemExit
{target_dir} already contains pet files; pass --force to ove
Error message
{target_dir} already contains pet files; pass --force to overwrite What it means
Raised by package_custom_pet.py when the target pet directory already contains spritesheet.webp or pet.json and --force was not passed. This protects an existing installed pet from being silently overwritten.
Source
Thrown at skills/hatch-pet/scripts/package_custom_pet.py:89
raise SystemExit("pet name is required")
pet_id = slugify(raw_pet_name)
if not pet_id:
raise SystemExit("pet name must contain at least one letter or digit")
display_name = (args.display_name or raw_pet_name).strip()
source = Path(args.spritesheet).expanduser().resolve()
source_format = validate_spritesheet(source)
target_dir = (
Path(args.output_dir).expanduser().resolve()
if args.output_dir
else Path(args.codex_home).expanduser().resolve() / "pets" / pet_id
)
target_dir.mkdir(parents=True, exist_ok=True)
target_sheet = target_dir / "spritesheet.webp"
manifest_path = target_dir / "pet.json"
if not args.force and (target_sheet.exists() or manifest_path.exists()):
raise SystemExit(f"{target_dir} already contains pet files; pass --force to overwrite")
write_webp_spritesheet(source, target_sheet, source_format)
manifest = {
"id": pet_id,
"displayName": display_name,
"description": args.description,
"spritesheetPath": target_sheet.name,
}
manifest_path.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
print(
json.dumps(
{"ok": True, "pet_dir": str(target_dir), "manifest": str(manifest_path)}, indent=2
)
)
if __name__ == "__main__":View on GitHub (pinned to 5be4028344)
Solutions
- Pass --force to overwrite the existing spritesheet.webp and pet.json.
- Or pick a different --pet-name / --output-dir to keep both versions.
- Confirm the existing pet.json is not one you want to preserve before using --force.
- Re-run with the chosen option.
Example fix
// before python package_custom_pet.py --pet-name Sprite --description "..." --spritesheet sheet.png # SystemExit: .../pets/sprite already contains pet files; pass --force to overwrite // after python package_custom_pet.py --pet-name Sprite --description "..." --spritesheet sheet.png --force
Defensive patterns
Strategy: validation
Validate before calling
def target_is_clean(target_dir: Path, force: bool) -> bool:
if force:
return True
sheet = target_dir / "spritesheet.webp"
manifest = target_dir / "pet.json"
return not (sheet.exists() or manifest.exists()) Prevention
- Pass --force when intentionally updating an existing pet.
- Use distinct --pet-name / --output-dir for parallel iterations to avoid clobbering.
- Back up the existing pet.json before repackaging with --force.
When it happens
Trigger: Re-packaging a pet into the same target_dir (default ${CODEX_HOME}/pets/<pet-id> or a custom --output-dir) where a previous package already wrote its files.
Common situations: Iterating on the same pet name without --force; reinstalling over an existing pet to update its spritesheet; default target resolving to a dir you already populated.
Related errors
- job manifest not found: {path}
- [last30days] Cannot read --synthesis-file: {exc}
- [CompetitorsPlan] Cannot read plan file: {exc}
- job manifest not found: {path}
- input image for job {job.get('id')} not found: {path}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/540b602e28680047.
Report an issue: GitHub.