nexu-io/open-design · error · SystemExit
pet name must contain at least one letter or digit
Error message
pet name must contain at least one letter or digit
What it means
Raised when the chosen pet name slugifies to an empty string. slugify strips non-[a-z0-9] characters and trims dashes, so a name consisting only of punctuation/whitespace (e.g. "!!!", "---", emojis) produces an empty id, which cannot become a folder name.
Source
Thrown at skills/hatch-pet/scripts/package_custom_pet.py:74
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--pet-name", default="")
parser.add_argument("--display-name", default="")
parser.add_argument("--description", required=True)
parser.add_argument("--spritesheet", required=True)
parser.add_argument("--codex-home", default=str(default_codex_home()))
parser.add_argument(
"--output-dir",
help="Exact pet package directory. Defaults to ${CODEX_HOME:-$HOME/.codex}/pets/<pet-name>.",
)
parser.add_argument("--force", action="store_true")
args = parser.parse_args()
raw_pet_name = (args.pet_name or args.display_name).strip()
if not raw_pet_name:
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 = {View on GitHub (pinned to 5be4028344)
Solutions
- Include at least one ASCII letter or digit in --pet-name / --display-name (e.g. "Pet #1" slugifies to "pet-1").
- Avoid purely symbolic or emoji-only names.
- Re-run with the corrected name.
Example fix
// before python package_custom_pet.py --pet-name "★★★" --description "..." --spritesheet sheet.png # SystemExit: pet name must contain at least one letter or digit // after python package_custom_pet.py --pet-name "Star Pet" --description "..." --spritesheet sheet.png
Defensive patterns
Strategy: validation
Validate before calling
import re
def slugify(value: str) -> str:
value = value.strip().lower()
value = re.sub(r"[^a-z0-9]+", "-", value)
value = re.sub(r"-{2,}", "-", value)
return value.strip("-")
if not slugify(raw_pet_name):
raise SystemExit("pet name must contain at least one letter or digit") Type guard
def slug_is_valid(value: str) -> bool:
import re
s = re.sub(r"[^a-z0-9]+", "-", value.strip().lower()).strip("-")
return bool(s) Prevention
- Include at least one ASCII letter or digit in pet names.
- Avoid emoji-only or punctuation-only names.
- Validate the slug client-side in any UI that drives the packager.
When it happens
Trigger: Passing --pet-name / --display-name whose only characters are symbols, spaces, or non-ASCII that slugify discards; a name made solely of emojis or punctuation.
Common situations: Creative names with only emojis/symbols; names in scripts whose only alphanumerics were stripped; a display name that is just decorative punctuation.
Related errors
- pet id must contain at least one letter or digit
- pet name is required
- invalid chroma key color: {value}; expected #RRGGBB
- invalid JSON in ${filePath}: ${message}
- ${filePath} must contain a JSON object
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/0d28427a22164f50.
Report an issue: GitHub.