{"record":{"id":"0df001967bf22da3","repo":"nexu-io/open-design","slug":"unknown-state-s-join-unknown-0df001","errorCode":null,"errorMessage":"unknown state(s): {', '.join(unknown)}","messagePattern":"unknown state\\(s\\): (.+?)","errorType":"exception","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"skills/hatch-pet/scripts/generate_pet_images.py","lineNumber":37,"sourceCode":"    \"running-right\",\n    \"running-left\",\n    \"waving\",\n    \"jumping\",\n    \"failed\",\n    \"waiting\",\n    \"running\",\n    \"review\",\n]\nCANONICAL_BASE_PATH = \"references/canonical-base.png\"\n\n\ndef parse_states(raw: str) -> list[str]:\n    if raw.strip().lower() == \"all\":\n        return ALL_STATES\n    states = [item.strip() for item in raw.split(\",\") if item.strip()]\n    unknown = sorted(set(states) - set(ALL_STATES))\n    if unknown:\n        raise SystemExit(f\"unknown state(s): {', '.join(unknown)}\")\n    return states\n\n\ndef load_manifest(run_dir: Path) -> dict[str, object]:\n    path = run_dir / \"imagegen-jobs.json\"\n    if not path.exists():\n        raise SystemExit(f\"job manifest not found: {path}\")\n    return json.loads(path.read_text(encoding=\"utf-8\"))\n\n\ndef manifest_jobs(manifest: dict[str, object]) -> list[dict[str, object]]:\n    jobs = manifest.get(\"jobs\")\n    if not isinstance(jobs, list):\n        raise SystemExit(\"invalid imagegen-jobs.json: jobs must be a list\")\n    return [job for job in jobs if isinstance(job, dict)]\n\n\ndef select_jobs(","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/skills/hatch-pet/scripts/generate_pet_images.py#L19-L55","documentation":"Raised by parse_states in generate_pet_images.py when the --states argument contains tokens not in ALL_STATES (idle, running-right, running-left, waving, jumping, failed, waiting, running, review). The literal 'all' expands to every state; anything else must match the canonical set exactly.","triggerScenarios":"Passing --states with a typo or unrecognized state name (e.g. 'runing-right', 'sleep') that is not in ALL_STATES and not the literal 'all'.","commonSituations":"Typing a state name from memory; using a state name from a different/older schema; case issues are tolerated only for the 'all' literal (it is lowercased), but individual state names are case-sensitive.","solutions":["Use --states all to process every canonical state.","Pass only state names from ALL_STATES: idle, running-right, running-left, waving, jumping, failed, waiting, running, review.","Copy the exact token from ALL_STATES in generate_pet_images.py to avoid typos."],"exampleFix":"// before\ngenerate_pet_images.py --run-dir r --states runing-left\n// after\ngenerate_pet_images.py --run-dir r --states running-left","handlingStrategy":"validation","validationCode":"ALL_STATES = {'idle','running-right','running-left','waving','jumping','failed','waiting','running','review'}\nraw = args.states\nstates = ALL_STATES if raw.strip().lower() == 'all' else {s.strip() for s in raw.split(',') if s.strip()}\nif unknown := states - ALL_STATES:\n    raise ValueError(f'unknown states: {sorted(unknown)}')","typeGuard":"ALL_STATES = {'idle','running-right','running-left','waving','jumping','failed','waiting','running','review'}\ndef is_state(value: str) -> bool:\n    return value in ALL_STATES","tryCatchPattern":null,"preventionTips":["Use --states all to avoid typos.","Copy state tokens directly from ALL_STATES in generate_pet_images.py.","Remember individual state names are case-sensitive (only 'all' is lowercased)."],"tags":["cli","states","enum","pet-pipeline"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}