nexu-io/open-design · error · SystemExit

job {args.job_id} has no output_path

Error message

job {args.job_id} has no output_path

What it means

Raised in record_imagegen_result.py main() when job.get('output_path') is not a string. The recorder copies the source to run_dir/<output_path> and writes metadata there, so a missing/non-string output_path means the manifest job is malformed and cannot be recorded against.

Source

Thrown at skills/hatch-pet/scripts/record_imagegen_result.py:198

    manifest_path = run_dir / "imagegen-jobs.json"
    manifest = load_jobs(manifest_path)
    job = find_job(manifest, args.job_id)

    missing_deps = [
        dep
        for dep in job.get("depends_on", [])
        if isinstance(dep, str) and dep not in completed_job_ids(manifest)
    ]
    if missing_deps:
        raise SystemExit(
            f"job {args.job_id} is not ready; missing dependency result(s): {', '.join(missing_deps)}"
        )
    validate_required_grounding(job, run_dir)

    output_raw = job.get("output_path")
    if not isinstance(output_raw, str):
        raise SystemExit(f"job {args.job_id} has no output_path")
    output = run_dir / output_raw
    if output.exists() and not args.force:
        raise SystemExit(f"{output} already exists; pass --force to replace it")

    output.parent.mkdir(parents=True, exist_ok=True)
    shutil.copy2(source, output)
    metadata = image_metadata(output)

    job["status"] = "complete"
    job["source_path"] = str(source)
    job["source_provenance"] = source_provenance
    job["source_sha256"] = file_sha256(source)
    job["output_sha256"] = file_sha256(output)
    if source_provenance == "synthetic-test":
        job["synthetic_test_source"] = True
    else:
        job.pop("synthetic_test_source", None)
    job["completed_at"] = datetime.now(timezone.utc).isoformat()

View on GitHub (pinned to 5be4028344)

Solutions

  1. Add a string output_path to the job, e.g. "output_path": "decoded/idle.png".
  2. Re-run prepare_pet_run.py --force to regenerate well-formed jobs.
  3. Validate: jq '.jobs[] | .output_path | type' imagegen-jobs.json (every entry should be 'string').
  4. Restore the manifest from version control.

Example fix

// before: {"id":"idle"}
// after:  {"id":"idle","output_path":"decoded/idle.png"}
Defensive patterns

Strategy: type-guard

Validate before calling

output_raw = job.get("output_path")
if not isinstance(output_raw, str) or not output_raw:
    raise SystemExit(f"job {job.get('id')} has no string output_path")

Type guard

def has_output_path(job: dict) -> bool:
    return isinstance(job.get("output_path"), str) and bool(job["output_path"])

Prevention

When it happens

Trigger: Job was defined without output_path; output_path is null or a number after a hand-edit; manifest schema drifted from what prepare produces.

Common situations: Manual job addition that omitted output_path; bad merge; older manifest format.

Related errors


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