nexu-io/open-design · error · SystemExit

job {job.get('id')} has invalid input image entry

Error message

job {job.get('id')} has invalid input image entry

What it means

Raised by path_list while iterating a job's input_images list: an element is not a dict, or its path field is not a string. Each input image must be an object with a string path.

Source

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

        "source_job": "base",
        "sha256": file_sha256(canonical),
    }
    manifest["canonical_identity_reference"] = reference
    request_path = run_dir / "pet_request.json"
    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()

View on GitHub (pinned to 5be4028344)

Solutions

  1. Inspect the failing job's input_images in imagegen-jobs.json.
  2. Make every entry an object {"path": "<relpath>", "role": "..."} with a string path.
  3. Regenerate the manifest with prepare_pet_run.py if many entries are malformed.
  4. Rerun the job.

Example fix

// before (manifest)
"input_images": [
  "references/canonical-base.png",
  {"role": "layout guide"}
]

// after
"input_images": [
  {"path": "references/canonical-base.png", "role": "canonical identity reference"},
  {"path": "references/layout-guides/idle.png", "role": "layout guide"}
]
Defensive patterns

Strategy: type-guard

Validate before calling

def valid_input_entry(item: object) -> bool:
    return isinstance(item, dict) and isinstance(item.get("path"), str)

Type guard

def is_input_entry(item: object) -> bool:
    return isinstance(item, dict) and isinstance(item.get("path"), str)

Prevention

When it happens

Trigger: An input_images array entry is a bare string path, a number, null, or a dict missing the path key (e.g. {"role": "..."} with no path).

Common situations: Hand-edited manifest using shorthand string paths instead of objects; a tool that writes input_images entries without the path key; mixing schemas from an older manifest version.

Related errors


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