nexu-io/open-design · error · SystemExit
review does not contain row-level results
Error message
review does not contain row-level results
What it means
Raised by rows_to_repair() in queue_pet_repairs.py when review.get('rows') is not a list. The repair loop depends on row-level QA results (each row carrying state/errors/warnings), so a review payload without a rows array is treated as a schema mismatch, not an empty repair set.
Source
Thrown at skills/hatch-pet/scripts/queue_pet_repairs.py:24
import argparse
import json
import shutil
from datetime import datetime, timezone
from pathlib import Path
def load_json(path: Path) -> dict[str, object]:
if not path.exists():
raise SystemExit(f"file not found: {path}")
return json.loads(path.read_text(encoding="utf-8"))
def rows_to_repair(
review: dict[str, object], *, repair_on_warnings: bool
) -> list[dict[str, object]]:
rows = review.get("rows")
if not isinstance(rows, list):
raise SystemExit("review does not contain row-level results")
repairs: list[dict[str, object]] = []
for row in rows:
if not isinstance(row, dict) or not isinstance(row.get("state"), str):
continue
errors = row.get("errors") if isinstance(row.get("errors"), list) else []
warnings = row.get("warnings") if isinstance(row.get("warnings"), list) else []
if errors or (repair_on_warnings and warnings):
repairs.append(
{
"state": row["state"],
"reason": "; ".join(str(item) for item in [*errors, *warnings])
or "the row did not pass visual QA",
}
)
return repairs
View on GitHub (pinned to 5be4028344)
Solutions
- Re-run the QA review so it emits a top-level rows: [...] array with per-row state/errors/warnings.
- Inspect the review file: jq '.rows | type' review.json should report 'array'.
- Confirm --review points at the row-level review artifact, not the manifest.
- If the schema genuinely changed, transform the file into {"rows": [...]} before retrying.
Example fix
# before: review.json = {"overall": "fail"}
# after: review.json = {"rows": [{"state": "idle", "errors": ["empty slot"]}]} Defensive patterns
Strategy: type-guard
Validate before calling
rows = review.get("rows")
if not isinstance(rows, list):
raise SystemExit("review.json must have a top-level 'rows' array; got " + type(rows).__name__) Type guard
def is_row_review(payload: object) -> bool:
return isinstance(payload, dict) and isinstance(payload.get("rows"), list) Prevention
- Freeze the QA review's output schema in a JSON schema and validate before repair.
- Have the reviewer write a schema_version field so mismatches are detectable.
- Unit-test rows_to_repair against a canonical review fixture.
When it happens
Trigger: Feeding a whole-run summary JSON (no per-row breakdown) as --review; the QA reviewer wrote a different top-level key (e.g. 'results' or 'frames'); the file is valid JSON but the wrong artifact entirely.
Common situations: QA pipeline changed its output schema between runs; reviewer emitted slide-level instead of row-level verdicts; user pointed --review at imagegen-jobs.json by mistake.
Related errors
- invalid imagegen-jobs.json: jobs must be a list
- unknown row job id: {state}
- invalid imagegen-jobs.json: jobs must be a list
- unknown job id: {job_id}
- job {job.get('id')} does not list input_images; grounded row
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/0fc84b4f4cea248c.
Report an issue: GitHub.