nexu-io/open-design · error · SystemExit

unknown job id: {job_id}

Error message

unknown job id: {job_id}

What it means

Thrown by find_job() in derive_running_left_from_running_right.py when no job in the manifest's jobs list has an 'id' equal to the requested job_id. The script looks up both 'running-right' and 'running-left', so either being absent triggers this.

Source

Thrown at skills/hatch-pet/scripts/derive_running_left_from_running_right.py:33

def load_manifest(run_dir: Path) -> dict[str, object]:
    path = run_dir / "imagegen-jobs.json"
    if not path.exists():
        raise SystemExit(f"job manifest not found: {path}")
    return json.loads(path.read_text(encoding="utf-8"))


def job_list(manifest: dict[str, object]) -> list[dict[str, object]]:
    jobs = manifest.get("jobs")
    if not isinstance(jobs, list):
        raise SystemExit("invalid imagegen-jobs.json: jobs must be a list")
    return [job for job in jobs if isinstance(job, dict)]


def find_job(manifest: dict[str, object], job_id: str) -> dict[str, object]:
    for job in job_list(manifest):
        if job.get("id") == job_id:
            return job
    raise SystemExit(f"unknown job id: {job_id}")


def file_sha256(path: Path) -> str:
    digest = hashlib.sha256()
    with path.open("rb") as file:
        for chunk in iter(lambda: file.read(1024 * 1024), b""):
            digest.update(chunk)
    return digest.hexdigest()


def image_metadata(path: Path) -> dict[str, object]:
    with Image.open(path) as image:
        image.verify()
    with Image.open(path) as image:
        return {
            "width": image.width,
            "height": image.height,
            "mode": image.mode,

View on GitHub (pinned to 5be4028344)

Solutions

  1. Inspect the manifest: list every job id and confirm both 'running-right' and 'running-left' exist.
  2. Run the imagegen steps that produce and register the running-right and running-left jobs before deriving.
  3. If ids were renamed, align the manifest ids back to the canonical 'running-right' / 'running-left'.

Example fix

// before
{"jobs": [{"id": "run-right", ...}]}
// after
{"jobs": [{"id": "running-right", ...}, {"id": "running-left", "mirror_policy": {"may_derive_from": "running-right"}}]}
Defensive patterns

Strategy: validation

Validate before calling

def assert_jobs_present(manifest, required_ids):
    have = {j.get("id") for j in manifest.get("jobs", [])}
    missing = [i for i in required_ids if i not in have]
    if missing:
        raise SystemExit(f"manifest missing job ids: {missing}")

assert_jobs_present(manifest, ["running-right", "running-left"])

Type guard

def job_exists(manifest, job_id) -> bool:
    return any(j.get("id") == job_id for j in manifest.get("jobs", []))

Prevention

When it happens

Trigger: Run derive_running_left_from_running_right.py against a manifest whose jobs list does not contain an entry with id 'running-right' or 'running-left' — e.g. only idle/waving jobs are present, or ids are spelled differently (e.g. 'run-right').

Common situations: Running the derive step before the running jobs were added to the manifest; id naming drift between the pipeline and this script; a manifest from a pet variant that does not define running animation.

Related errors


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