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
- Inspect the manifest: list every job id and confirm both 'running-right' and 'running-left' exist.
- Run the imagegen steps that produce and register the running-right and running-left jobs before deriving.
- 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
- Confirm both 'running-right' and 'running-left' job entries exist before deriving.
- Keep job ids canonical; do not rename them per pet variant.
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
- invalid imagegen-jobs.json: jobs must be a list
- job manifest not found: {path}
- running-right must be complete before deriving running-left
- running-left is not configured for conditional mirroring
- job {job_id} has no {field}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/527319469c4cef4a.
Report an issue: GitHub.