HKUDS/Vibe-Trading · error · ValueError
audit rows require criterion_id and result
Error message
audit rows require criterion_id and result
What it means
Each audit row dict must carry non-empty criterion_id and result after stripping. This ensures the audit trail is actually attributable to a criterion. Missing keys, empty strings, or whitespace-only values all trigger it.
Source
Thrown at agent/src/tools/goal_tool.py:51
def _coerce_audit_rows(value: Any) -> list[AuditRow]:
"""Coerce model/API-style audit rows into dataclasses."""
if value in (None, ""):
return []
if isinstance(value, str):
value = json.loads(value)
if not isinstance(value, list):
raise ValueError("audit must be a list")
rows: list[AuditRow] = []
for item in value:
if not isinstance(item, dict):
raise ValueError("audit rows must be objects")
criterion_id = str(item.get("criterion_id") or "").strip()
result = str(item.get("result") or "").strip()
if not criterion_id or not result:
raise ValueError("audit rows require criterion_id and result")
rows.append(
AuditRow(
criterion_id=criterion_id,
result=result,
evidence_ids=_coerce_string_list(item.get("evidence_ids")),
notes=str(item.get("notes") or ""),
)
)
return rows
def _sha256_file(path: Path) -> str:
"""Return the sha256 digest for a local artifact."""
digest = hashlib.sha256()
with path.open("rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()View on GitHub (pinned to 80ffdda44c)
Solutions
- Populate criterion_id and result on every row
- Skip empty rows before submission: rows=[r for r in rows if r.get('criterion_id') and r.get('result')]
- Add client-side required-field validation for the audit form
Example fix
# before
{"criterion_id": "c1"}
# after
{"criterion_id": "c1", "result": "pass"} Defensive patterns
Strategy: validation
Validate before calling
audit = [r for r in audit if str(r.get("criterion_id", "")).strip() and str(r.get("result", "")).strip()] Type guard
def row_is_complete(r: dict) -> bool:
return bool(str(r.get("criterion_id") or "").strip() and str(r.get("result") or "").strip()) Try / catch
try:
execute(audit=audit)
except ValueError as e:
if "require criterion_id and result" in str(e):
audit = [r for r in audit if row_is_complete(r)]
execute(audit=audit)
raise Prevention
- Filter empty rows before submission
- Make criterion_id/result required in form/schema validation
When it happens
Trigger: audit=[{"criterion_id": "", "result": "pass"}] or a row with only notes/evidence but no ids.
Common situations: LLM omitting fields it considers obvious; partial dicts merged from templates; frontend forms not enforcing required inputs.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- title is required
- thesis is required
- memory name must not be empty or whitespace-only
- audit must be a list
- audit rows must be objects
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/ea96b72ab33c216c.
Report an issue: GitHub.