{"record":{"id":"73b7acda81a0c163","repo":"nexu-io/open-design","slug":"pet-name-is-required","errorCode":null,"errorMessage":"pet name is required","messagePattern":"pet name is required","errorType":"exception","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"skills/hatch-pet/scripts/package_custom_pet.py","lineNumber":71,"sourceCode":"\n\ndef main() -> None:\n    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\")","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/skills/hatch-pet/scripts/package_custom_pet.py#L53-L89","documentation":"Raised by package_custom_pet.py main() when both --pet-name and --display-name are empty after stripping. The packager needs at least one of them to derive the pet id and folder name.","triggerScenarios":"Invoking the script with neither --pet-name nor --display-name, or passing only whitespace to both.","commonSituations":"Assuming --display-name is required (it is not; --description and --spritesheet are); running the script with an empty shell variable expansion (e.g. --pet-name \"$PET\" where PET is unset).","solutions":["Pass --pet-name \"My Pet\" or --display-name \"My Pet\".","If passing via a variable, ensure it is set and non-empty, e.g. --pet-name \"${PET:?PET is unset}\".","Re-run with the name supplied."],"exampleFix":"// before\npython package_custom_pet.py --description \"...\" --spritesheet sheet.png\n# SystemExit: pet name is required\n\n// after\npython package_custom_pet.py --pet-name \"Sprite\" --description \"...\" --spritesheet sheet.png","handlingStrategy":"validation","validationCode":"raw_pet_name = (args.pet_name or args.display_name).strip()\nif not raw_pet_name:\n    raise SystemExit(\"pet name is required\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass --pet-name or --display-name when packaging.","If sourcing from a variable, guard it: --pet-name \"${PET:?PET is unset}\".","Add a wrapper script that asserts the name before invoking the packager."],"tags":["cli","arguments","validation","system-exit"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}