nexu-io/open-design · error · SystemExit

could not find {frame_count} sprite components in {strip_pat

Error message

could not find {frame_count} sprite components in {strip_path}

What it means

With --method components (explicit), extract_component_frames could not find frame_count distinct connected sprite blobs (seeds) in the chroma-keyed strip and returned None, so the script aborts instead of silently falling back to slots. In --method auto it would fall back to equal slots instead of erroring.

Source

Thrown at skills/hatch-pet/scripts/extract_strip_frames.py:252

    state: str,
    output_root: Path,
    chroma_key: tuple[int, int, int],
    threshold: float,
    method: str,
) -> dict[str, object]:
    frame_count = ROW_FRAME_COUNTS[state]
    with Image.open(strip_path) as opened:
        strip = remove_chroma_background(opened, chroma_key, threshold)

    state_dir = output_root / state
    state_dir.mkdir(parents=True, exist_ok=True)

    frames = None
    used_method = method
    if method in {"auto", "components"}:
        frames = extract_component_frames(strip, frame_count)
        if frames is None and method == "components":
            raise SystemExit(f"could not find {frame_count} sprite components in {strip_path}")
        if frames is not None:
            used_method = "components"

    if frames is None:
        frames = extract_slot_frames(strip, frame_count)
        used_method = "slots"

    outputs = []
    for index, frame in enumerate(frames):
        output = state_dir / f"{index:02d}.png"
        frame.save(output)
        outputs.append(str(output))
    return {"state": state, "frames": outputs, "method": used_method}


def main() -> None:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--decoded-dir", required=True)

View on GitHub (pinned to 5be4028344)

Solutions

  1. Use --method auto (the default) so extraction can fall back to equal slots when components fail.
  2. Tune --key-threshold so the chroma background is removed without erasing sprite edges.
  3. Verify or override --chroma-key to match the strip's actual background color.
  4. If sprites genuinely overlap, regenerate the strip so frames are visually separated.

Example fix

# before
--method components
# after
--method auto
Defensive patterns

Strategy: try-catch

Validate before calling

from pathlib import Path
from PIL import Image

strip_path = Path("<decoded_dir>/<state>.png")
with Image.open(strip_path) as img:
    print("size:", img.size, "mode:", img.mode)
# Inspect visually first; components method needs visually separated sprites.

Try / catch

import subprocess, sys

result = subprocess.run([sys.executable, "extract_strip_frames.py", "--method", "components", ...])
if result.returncode != 0:
    # fall back to auto/slots instead of failing the whole pipeline
    subprocess.run([sys.executable, "extract_strip_frames.py", "--method", "auto", ...], check=True)

Prevention

When it happens

Trigger: Passing --method components on a strip whose sprites are touching/overlapping (one connected blob), have low alpha contrast against the background, or whose chroma threshold erased too much of the sprite.

Common situations: Generated sprites bleeding together; a wrong chroma key that eats sprite edges; a sparse strip with fewer distinct figures than the expected frame count for that state.

Related errors


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