{"record":{"id":"2b8acc2e27177e26","repo":"nexu-io/open-design","slug":"job-job-get-id-has-an-invalid-input-image-ent","errorCode":null,"errorMessage":"job {job.get('id')} has an invalid input image entry","messagePattern":"job (.+?) has an invalid input image entry","errorType":"exception","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"skills/hatch-pet/scripts/record_imagegen_result.py","lineNumber":118,"sourceCode":"            \"source image does not look like a built-in $imagegen output; expected \"\n            f\"{generated_root}/.../ig_*.png. Do not ingest locally drawn or \"\n            \"post-processed row strips as visual job outputs.\"\n        )\n    return \"built-in-imagegen\"\n\n\ndef validate_required_grounding(job: dict[str, object], run_dir: Path) -> None:\n    if job.get(\"allow_prompt_only_generation\") is not False:\n        return\n    inputs = job.get(\"input_images\")\n    if not isinstance(inputs, list) or not inputs:\n        raise SystemExit(\n            f\"job {job.get('id')} does not list input_images; grounded row jobs must attach references\"\n        )\n    missing = []\n    for item in inputs:\n        if not isinstance(item, dict) or not isinstance(item.get(\"path\"), str):\n            raise SystemExit(f\"job {job.get('id')} has an invalid input image entry\")\n        path = run_dir / item[\"path\"]\n        if not path.is_file():\n            missing.append(str(path))\n    if missing:\n        raise SystemExit(\n            f\"job {job.get('id')} is missing required grounding image(s): \"\n            + \", \".join(missing)\n        )\n\n\ndef update_base_canonical_reference(\n    *,\n    run_dir: Path,\n    output: Path,\n    manifest: dict[str, object],\n    job: dict[str, object],\n    metadata: dict[str, object],\n) -> None:","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/skills/hatch-pet/scripts/record_imagegen_result.py#L100-L136","documentation":"Raised by validate_required_grounding() in record_imagegen_result.py when an entry inside a grounded job's input_images is not a dict, or its 'path' field is not a string. Each grounding entry must be an object with a string path so the recorder can resolve run_dir/<path> and confirm the file exists.","triggerScenarios":"input_images contains a bare string path instead of an object; an entry is missing the 'path' key; an entry is null or a number from a hand-edit.","commonSituations":"Manual schema drift ('I'll just put the path string'); copy-paste from a different manifest format; bad JSON merge.","solutions":["Wrap each entry as an object: {\"path\": \"references/canonical-base.png\"}.","Validate: jq '.jobs[] | select(.allow_prompt_only_generation==false) | .input_images[] | .path | type' imagegen-jobs.json.","Re-run prepare_pet_run.py --force to regenerate well-formed input_images.","Remove malformed entries that are not real grounding references."],"exampleFix":"// before: \"input_images\": [\"references/canonical-base.png\"]\n// after:  \"input_images\": [{\"path\":\"references/canonical-base.png\"}]","handlingStrategy":"type-guard","validationCode":"for item in inputs:\n    if not isinstance(item, dict) or not isinstance(item.get(\"path\"), str):\n        raise SystemExit(f\"job {job.get('id')} has a malformed input_images entry: {item!r}\")","typeGuard":"def is_valid_input_entry(item: object) -> bool:\n    return isinstance(item, dict) and isinstance(item.get(\"path\"), str)","tryCatchPattern":null,"preventionTips":["Use the {\"path\": ...} object form for every input_images entry.","Validate the manifest with jsonschema before recording.","Avoid editing input_images by hand."],"tags":["data-validation","cli","hatch-pet","schema"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}