nexu-io/open-design · error · SystemExit

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

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.

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)

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.