{"record":{"id":"90061a46737e2327","repo":"nexu-io/open-design","slug":"job-job-id-source-image-is-not-a-built-in-image","errorCode":null,"errorMessage":"job {job_id} source image is not a built-in $imagegen output under {generated_root}/.../ig_*.png","messagePattern":"job (.+?) source image is not a built-in \\$imagegen output under (.+?)/\\.\\.\\./ig_\\*\\.png","errorType":"exception","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"skills/hatch-pet/scripts/finalize_pet_run.py","lineNumber":174,"sourceCode":"        return\n\n    if job.get(\"source_provenance\") == \"deterministic-mirror\":\n        validate_mirror_hash(job, source=source, output=output, job_id=job_id)\n        return\n\n    if job.get(\"source_provenance\") != \"built-in-imagegen\":\n        raise SystemExit(\n            f\"job {job_id} was not recorded as a built-in $imagegen output; \"\n            \"use record_imagegen_result.py with the selected $CODEX_HOME/generated_images/.../ig_*.png file\"\n        )\n    if is_relative_to(source, run_dir):\n        raise SystemExit(\n            f\"job {job_id} source image is inside the pet run directory; \"\n            \"do not use locally generated row artifacts as visual sources\"\n        )\n    generated_root = default_generated_images_root()\n    if not is_relative_to(source, generated_root) or not source.name.startswith(\"ig_\"):\n        raise SystemExit(\n            f\"job {job_id} source image is not a built-in $imagegen output under \"\n            f\"{generated_root}/.../ig_*.png\"\n        )\n    validate_hash(job, source=source, output=output, job_id=job_id)\n\n\ndef require_complete_jobs(run_dir: Path, *, allow_synthetic_test_sources: bool) -> None:\n    manifest_path = run_dir / \"imagegen-jobs.json\"\n    manifest = load_json(manifest_path)\n    jobs = manifest.get(\"jobs\")\n    if not isinstance(jobs, list):\n        raise SystemExit(\"invalid imagegen-jobs.json: jobs must be a list\")\n    incomplete = [\n        str(job.get(\"id\"))\n        for job in jobs\n        if isinstance(job, dict) and job.get(\"status\", \"pending\") != \"complete\"\n    ]\n    if incomplete:","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/skills/hatch-pet/scripts/finalize_pet_run.py#L156-L192","documentation":"Raised by validate_completed_job_source when a built-in-imagegen job's source_path is not located under default_generated_images_root() ($CODEX_HOME/generated_images) or its filename does not start with 'ig_'. This enforces that the recorded source is a genuine Codex $imagegen output artifact.","triggerScenarios":"is_relative_to(source, generated_root) is false OR source.name does not start with 'ig_'. The CODEX_HOME env var may resolve somewhere unexpected, or the source file is not a Codex-generated ig_*.png.","commonSituations":"CODEX_HOME unset or pointing at a non-default location so generated_root differs from where the file lives; recording a manually named PNG instead of the original ig_*.png; sourcing from a different tool's output directory.","solutions":["Set CODEX_HOME (or rely on ~/.codex) so default_generated_images_root() matches the directory holding the ig_*.png file.","Use record_imagegen_result.py to point source_path at the real $CODEX_HOME/generated_images/.../ig_*.png file.","Confirm the source filename retains the original ig_ prefix assigned by Codex imagegen."],"exampleFix":"// before (env)\nCODEX_HOME=/custom/codex  # but source is under ~/.codex/generated_images\n// after\nunset CODEX_HOME  # or export CODEX_HOME=$HOME/.codex","handlingStrategy":"validation","validationCode":"import os\nfrom pathlib import Path\ngenerated_root = Path(os.environ.get('CODEX_HOME') or '~/.codex').expanduser().resolve() / 'generated_images'\nif not is_relative_to(source, generated_root) or not source.name.startswith('ig_'):\n    raise RuntimeError(f'source must be under {generated_root}/.../ig_*.png')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep CODEX_HOME consistent between imagegen and finalize.","Preserve the original ig_*.png filename assigned by Codex.","Use record_imagegen_result.py to choose and record the correct source file."],"tags":["path-validation","codex-home","provenance","pet-pipeline"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}