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

  1. Include at least one ASCII letter or digit in --pet-name / --display-name (e.g. "Pet #1" slugifies to "pet-1").
  2. Avoid purely symbolic or emoji-only names.
  3. 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

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


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/0d28427a22164f50. Report an issue: GitHub.