{"record":{"id":"0d28427a22164f50","repo":"nexu-io/open-design","slug":"pet-name-must-contain-at-least-one-letter-or-digit","errorCode":null,"errorMessage":"pet name must contain at least one letter or digit","messagePattern":"pet name must contain at least one letter or digit","errorType":"exception","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"skills/hatch-pet/scripts/package_custom_pet.py","lineNumber":74,"sourceCode":"    parser = argparse.ArgumentParser(description=__doc__)\n    parser.add_argument(\"--pet-name\", default=\"\")\n    parser.add_argument(\"--display-name\", default=\"\")\n    parser.add_argument(\"--description\", required=True)\n    parser.add_argument(\"--spritesheet\", required=True)\n    parser.add_argument(\"--codex-home\", default=str(default_codex_home()))\n    parser.add_argument(\n        \"--output-dir\",\n        help=\"Exact pet package directory. Defaults to ${CODEX_HOME:-$HOME/.codex}/pets/<pet-name>.\",\n    )\n    parser.add_argument(\"--force\", action=\"store_true\")\n    args = parser.parse_args()\n\n    raw_pet_name = (args.pet_name or args.display_name).strip()\n    if not raw_pet_name:\n        raise SystemExit(\"pet name is required\")\n    pet_id = slugify(raw_pet_name)\n    if not pet_id:\n        raise SystemExit(\"pet name must contain at least one letter or digit\")\n    display_name = (args.display_name or raw_pet_name).strip()\n\n    source = Path(args.spritesheet).expanduser().resolve()\n    source_format = validate_spritesheet(source)\n    target_dir = (\n        Path(args.output_dir).expanduser().resolve()\n        if args.output_dir\n        else Path(args.codex_home).expanduser().resolve() / \"pets\" / pet_id\n    )\n    target_dir.mkdir(parents=True, exist_ok=True)\n\n    target_sheet = target_dir / \"spritesheet.webp\"\n    manifest_path = target_dir / \"pet.json\"\n    if not args.force and (target_sheet.exists() or manifest_path.exists()):\n        raise SystemExit(f\"{target_dir} already contains pet files; pass --force to overwrite\")\n\n    write_webp_spritesheet(source, target_sheet, source_format)\n    manifest = {","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/skills/hatch-pet/scripts/package_custom_pet.py#L56-L92","documentation":"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.","triggerScenarios":"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.","commonSituations":"Creative names with only emojis/symbols; names in scripts whose only alphanumerics were stripped; a display name that is just decorative punctuation.","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."],"exampleFix":"// before\npython package_custom_pet.py --pet-name \"★★★\" --description \"...\" --spritesheet sheet.png\n# SystemExit: pet name must contain at least one letter or digit\n\n// after\npython package_custom_pet.py --pet-name \"Star Pet\" --description \"...\" --spritesheet sheet.png","handlingStrategy":"validation","validationCode":"import re\n\ndef slugify(value: str) -> str:\n    value = value.strip().lower()\n    value = re.sub(r\"[^a-z0-9]+\", \"-\", value)\n    value = re.sub(r\"-{2,}\", \"-\", value)\n    return value.strip(\"-\")\n\nif not slugify(raw_pet_name):\n    raise SystemExit(\"pet name must contain at least one letter or digit\")","typeGuard":"def slug_is_valid(value: str) -> bool:\n    import re\n    s = re.sub(r\"[^a-z0-9]+\", \"-\", value.strip().lower()).strip(\"-\")\n    return bool(s)","tryCatchPattern":null,"preventionTips":["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."],"tags":["cli","slugify","validation","system-exit"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}