nexu-io/open-design · error · SystemExit

input image for job not found

Error message

input image for job {job.get('id')} not found: {path}

What it means

Raised by path_list when an input_images entry resolves inside run_dir but no file exists at that resolved path. The script will not call the image API until every declared input image is present.

Solutions

  1. Run the base job first (--job-id base, or omit --skip-base) so decoded/base.png exists.
  2. Confirm --run-dir points at the dir that contains imagegen-jobs.json and its decoded/references subfolders.
  3. If files were deleted, regenerate the run dir with prepare_pet_run.py.
  4. Use pet_job_status.py --run-dir <dir> to see which jobs are ready vs blocked by missing dependencies.

Example fix

// before
python generate_pet_images.py --run-dir /tmp/pet-run --job-id idle
# fails: decoded/base.png not found

// after - generate base first, then rows
python generate_pet_images.py --run-dir /tmp/pet-run --job-id base
python generate_pet_images.py --run-dir /tmp/pet-run --states idle,waving
Defensive patterns

Strategy: validation

Validate before calling

def ensure_inputs_exist(run_dir: Path, job: dict) -> None:
    for item in job.get("input_images", []):
        path = (run_dir / item["path"]).resolve()
        if not path.is_file():
            raise SystemExit(f"missing input: {path}")

Prevention

When it happens

Trigger: The manifest references decoded/base.png or references/layout-guides/<state>.png before that dependency has been generated/copied, or a previously generated file was deleted/moved.

Common situations: Running a row-strip job before the base job completed (decoded/base.png missing); running generate_pet_images.py against a partial run dir; deleted intermediate files; wrong run_dir passed to --run-dir.

Related errors


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

Appendix: source

Thrown at skills/hatch-pet/scripts/generate_pet_images.py:221

    if request_path.exists():
        request = json.loads(request_path.read_text(encoding="utf-8"))
        request["canonical_identity_reference"] = reference
        request_path.write_text(json.dumps(request, indent=2) + "\n", encoding="utf-8")


def path_list(run_dir: Path, job: dict[str, object]) -> list[Path]:
    inputs = job.get("input_images")
    if not isinstance(inputs, list):
        raise SystemExit(f"job {job.get('id')} has invalid input_images")
    paths = []
    for item in inputs:
        if not isinstance(item, dict) or not isinstance(item.get("path"), str):
            raise SystemExit(f"job {job.get('id')} has invalid input image entry")
        path = (run_dir / item["path"]).resolve()
        if not path.is_relative_to(run_dir):
            raise SystemExit(f"path traversal detected in input_images for job {job.get('id')}")
        if not path.is_file():
            raise SystemExit(f"input image for job {job.get('id')} not found: {path}")
        paths.append(path)
    return paths


def main() -> None:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--run-dir", required=True)
    parser.add_argument("--model", default="gpt-image-2")
    parser.add_argument("--size", default="1024x1024")
    parser.add_argument("--states", default="all")
    parser.add_argument("--job-id", action="append", default=[])
    parser.add_argument("--skip-base", action="store_true")
    args = parser.parse_args()

    api_key = os.environ.get("OPENAI_API_KEY")
    if not api_key:
        raise SystemExit("OPENAI_API_KEY is not set")

View on GitHub (pinned to 5be4028344)