{"record":{"id":"558339f1a4ab42ac","repo":"nexu-io/open-design","slug":"unknown-state-s-join-unknown","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/extract_strip_frames.py","lineNumber":35,"sourceCode":"    \"idle\": 6,\n    \"running-right\": 8,\n    \"running-left\": 8,\n    \"waving\": 4,\n    \"jumping\": 5,\n    \"failed\": 8,\n    \"waiting\": 6,\n    \"running\": 6,\n    \"review\": 6,\n}\n\n\ndef parse_states(raw: str) -> list[str]:\n    if raw.strip().lower() == \"all\":\n        return list(ROW_FRAME_COUNTS)\n    states = [item.strip() for item in raw.split(\",\") if item.strip()]\n    unknown = sorted(set(states) - set(ROW_FRAME_COUNTS))\n    if unknown:\n        raise SystemExit(f\"unknown state(s): {', '.join(unknown)}\")\n    return states\n\n\ndef parse_hex_color(value: str) -> tuple[int, int, int]:\n    if not re.fullmatch(r\"#[0-9a-fA-F]{6}\", value):\n        raise SystemExit(f\"invalid chroma key color: {value}; expected #RRGGBB\")\n    return tuple(int(value[index : index + 2], 16) for index in (1, 3, 5))\n\n\ndef load_chroma_key(decoded_dir: Path, override: str | None) -> tuple[int, int, int]:\n    if override:\n        return parse_hex_color(override)\n    request_path = decoded_dir.parent / \"pet_request.json\"\n    if request_path.is_file():\n        request = json.loads(request_path.read_text(encoding=\"utf-8\"))\n        chroma_key = request.get(\"chroma_key\")\n        if isinstance(chroma_key, dict) and isinstance(chroma_key.get(\"hex\"), str):\n            return parse_hex_color(chroma_key[\"hex\"])","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/skills/hatch-pet/scripts/extract_strip_frames.py#L17-L53","documentation":"parse_states rejects any --states token that is not a key of ROW_FRAME_COUNTS (idle, running-right, running-left, waving, jumping, failed, waiting, running, review). The literal \"all\" expands to every known state; anything else must match exactly. Unknown tokens are collected, sorted, and reported comma-joined.","triggerScenarios":"Passing --states with a typo (e.g. runing-right), an outdated name, or an unsupported state like foo. Whitespace around tokens is trimmed, but spelling must match exactly.","commonSituations":"Typos on the command line; copy-pasting state names from stale docs; referencing a state that was renamed or not yet added to ROW_FRAME_COUNTS.","solutions":["Cross-check the token against the ROW_FRAME_COUNTS keys in extract_strip_frames.py.","Use --states all to process every supported state without listing them.","Fix the typo or remove the unknown token from the comma-separated list."],"exampleFix":"# before\n--states idle,runing-right\n# after\n--states idle,running-right","handlingStrategy":"validation","validationCode":"ROW_FRAME_COUNTS = {\"idle\", \"running-right\", \"running-left\", \"waving\", \"jumping\", \"failed\", \"waiting\", \"running\", \"review\"}\n\nraw = \"idle,foo\"\nstates = {s.strip() for s in raw.split(\",\") if s.strip()} if raw.strip().lower() != \"all\" else ROW_FRAME_COUNTS\nunknown = sorted(states - ROW_FRAME_COUNTS)\nassert not unknown, f\"unknown state(s): {', '.join(unknown)}\"","typeGuard":"def is_known_state(raw: str) -> bool:\n    from extract_strip_frames import ROW_FRAME_COUNTS\n    return raw.strip().lower() == \"all\" or all(s.strip() in ROW_FRAME_COUNTS for s in raw.split(\",\"))","tryCatchPattern":null,"preventionTips":["Prefer --states all unless you specifically need a subset.","Copy state names directly from ROW_FRAME_COUNTS to avoid typos.","Validate the --states list in your wrapper before invoking the script."],"tags":["hatch-pet","cli-args","states","validation"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}