HKUDS/Vibe-Trading · error · ValueError
criterion {criterion.criterion_id} is not satisfied
Error message
criterion {criterion.criterion_id} is not satisfied What it means
A completion audit row carried a result value outside _COMPLETION_RESULTS (the allowed satisfied/satisfied_with_caveat/not_applicable set), so the criterion counts as unsatisfied and completion is refused.
Source
Thrown at agent/src/goal/store.py:913
if row is None:
raise ValueError(f"unknown claim_id: {claim_id}")
return self._claim_from_row(row)
def _validate_completion_audit(
self,
goal: GoalRecord,
audit: list[AuditRow],
) -> None:
criteria = self.list_criteria(goal.goal_id)
rows_by_criterion = {row.criterion_id: row for row in audit}
for criterion in criteria:
if not criterion.required:
continue
row = rows_by_criterion.get(criterion.criterion_id)
if row is None:
raise ValueError(f"missing audit row for criterion {criterion.criterion_id}")
if row.result not in _COMPLETION_RESULTS:
raise ValueError(f"criterion {criterion.criterion_id} is not satisfied")
if row.result in {"satisfied", "satisfied_with_caveat"} and not row.evidence_ids:
raise ValueError("complete goals require verified evidence")
if row.result == "not_applicable_user_accepted" and not row.notes.strip():
raise ValueError("not-applicable criteria require acceptance notes")
has_verified_evidence = False
for evidence_id in row.evidence_ids:
evidence = self._get_evidence(evidence_id)
if evidence is None or evidence.goal_id != goal.goal_id:
raise ValueError(f"unknown evidence_id: {evidence_id}")
if evidence.criterion_id != criterion.criterion_id:
raise ValueError(
f"evidence {evidence_id} does not match criterion {criterion.criterion_id}"
)
if evidence.verification_status == "verified":
has_verified_evidence = True
if row.result in {"satisfied", "satisfied_with_caveat"} and not has_verified_evidence:
raise ValueError("complete goals require verified evidence")
View on GitHub (pinned to 80ffdda44c)
Solutions
- Use only the allowed result literals: satisfied, satisfied_with_caveat, not_applicable_user_accepted (check _COMPLETION_RESULTS in your version)
- Validate/normalize LLM-produced result strings against the allowed set before building audit rows
- If a criterion truly is unsatisfied, the goal cannot be completed yet — gather evidence first
Example fix
// before
AuditRow(criterion_id="c1", result="done", evidence_ids=[...])
// after
_ALLOWED = {"satisfied", "satisfied_with_caveat", "not_applicable_user_accepted"}
result = result if result in _ALLOWED else "satisfied"
AuditRow(criterion_id="c1", result=result, evidence_ids=[...]) Defensive patterns
Strategy: validation
Validate before calling
ALLOWED = {"satisfied", "satisfied_with_caveat", "not_applicable_user_accepted"}
assert all(row.result in ALLOWED for row in audit), [r.result for r in audit if r.result not in ALLOWED] Type guard
def is_valid_result(result: str) -> bool:
return result in {"satisfied", "satisfied_with_caveat", "not_applicable_user_accepted"} Try / catch
except ValueError as e: if 'not satisfied' in str(e): normalize result strings and re-validate before retrying
Prevention
- Centralize the allowed-result constants
- Constrain LLM outputs to an enum/choice set
- Pin the library version when result literals matter
When it happens
Trigger: update_status with an audit row whose result is e.g. "unsatisfied", "pending", or a typo like "satisifed".
Common situations: Result strings built by LLM output or dynamic code; enum/str mismatch after a version change renaming result values.
Related errors
- missing audit row for criterion {criterion.criterion_id}
- complete goals require verified evidence
- not-applicable criteria require acceptance notes
- unknown evidence_id: {evidence_id}
- evidence {evidence_id} does not match criterion {criterion.c
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/01e49369ae006164.
Report an issue: GitHub.