HKUDS/Vibe-Trading · error · ValueError

evidence {evidence_id} does not match criterion {criterion.c

Error message

evidence {evidence_id} does not match criterion {criterion.criterion_id}

What it means

A cited evidence record exists and belongs to the goal, but its criterion_id differs from the criterion of the audit row citing it. Evidence is scoped per criterion and cannot be reused across criteria in the audit.

Source

Thrown at agent/src/goal/store.py:924

        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")

    def _get_evidence(self, evidence_id: str) -> EvidenceRecord | None:
        row = self._conn.execute(
            "SELECT * FROM goal_evidence WHERE evidence_id = ?",
            (evidence_id,),
        ).fetchone()
        return self._evidence_from_row(row) if row else None

    @staticmethod
    def _goal_from_row(row: sqlite3.Row) -> GoalRecord:
        return GoalRecord(
            goal_id=row["goal_id"],

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Append criterion-specific evidence for each criterion and cite only matching ids
  2. If the evidence genuinely covers both criteria, append it once per criterion (or restructure criteria)
  3. When building the audit, filter evidence by criterion_id

Example fix

// before
AuditRow(criterion_id="c1", result="satisfied", evidence_ids=[ev_for_c2.evidence_id])
// after
ev_c1 = store.append_evidence(session_id, goal_id, criterion_id="c1", ...)
AuditRow(criterion_id="c1", result="satisfied", evidence_ids=[ev_c1.evidence_id])
Defensive patterns

Strategy: validation

Validate before calling

by_crit = {}
for e in store.list_evidence(goal_id):
    by_crit.setdefault(e.criterion_id, []).append(e.evidence_id)
audit = [AuditRow(criterion_id=cid, result=..., evidence_ids=by_crit.get(cid, [])) for cid in required]

Type guard

def evidence_matches_criterion(store, evidence_id: str, criterion_id: str) -> bool:
    e = store._get_evidence(evidence_id)
    return e is not None and e.criterion_id == criterion_id

Try / catch

except ValueError as e: if 'does not match criterion' in str(e): re-map evidence per criterion and retry update_status

Prevention

When it happens

Trigger: update_status where a row for criterion A lists evidence appended against criterion B (same goal).

Common situations: Reusing one strong piece of evidence to satisfy multiple criteria; criterion ids shifted after criteria were reordered/recreated.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/1fb3c8a3c43e3dd5. Report an issue: GitHub.