{"record":{"id":"3233f0ccad33bfdd","repo":"HKUDS/Vibe-Trading","slug":"missing-audit-row-for-criterion-criterion-criteri","errorCode":null,"errorMessage":"missing audit row for criterion {criterion.criterion_id}","messagePattern":"missing audit row for criterion (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/goal/store.py","lineNumber":911,"sourceCode":"            (goal_id, claim_id),\n        ).fetchone()\n        if row is None:\n            raise ValueError(f\"unknown claim_id: {claim_id}\")\n        return self._claim_from_row(row)\n\n    def _validate_completion_audit(\n        self,\n        goal: GoalRecord,\n        audit: list[AuditRow],\n    ) -> None:\n        criteria = self.list_criteria(goal.goal_id)\n        rows_by_criterion = {row.criterion_id: row for row in audit}\n        for criterion in criteria:\n            if not criterion.required:\n                continue\n            row = rows_by_criterion.get(criterion.criterion_id)\n            if row is None:\n                raise ValueError(f\"missing audit row for criterion {criterion.criterion_id}\")\n            if row.result not in _COMPLETION_RESULTS:\n                raise ValueError(f\"criterion {criterion.criterion_id} is not satisfied\")\n            if row.result in {\"satisfied\", \"satisfied_with_caveat\"} and not row.evidence_ids:\n                raise ValueError(\"complete goals require verified evidence\")\n            if row.result == \"not_applicable_user_accepted\" and not row.notes.strip():\n                raise ValueError(\"not-applicable criteria require acceptance notes\")\n            has_verified_evidence = False\n            for evidence_id in row.evidence_ids:\n                evidence = self._get_evidence(evidence_id)\n                if evidence is None or evidence.goal_id != goal.goal_id:\n                    raise ValueError(f\"unknown evidence_id: {evidence_id}\")\n                if evidence.criterion_id != criterion.criterion_id:\n                    raise ValueError(\n                        f\"evidence {evidence_id} does not match criterion {criterion.criterion_id}\"\n                    )\n                if evidence.verification_status == \"verified\":\n                    has_verified_evidence = True\n            if row.result in {\"satisfied\", \"satisfied_with_caveat\"} and not has_verified_evidence:","sourceCodeStart":893,"sourceCodeEnd":929,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/goal/store.py#L893-L929","documentation":"When moving a goal to a completed status, update_status runs _validate_completion_audit, which requires an audit row for every required criterion. This error means a required criterion had no row in the audit list.","triggerScenarios":"Calling update_status(goal_id, status=completed-ish, audit=[...]) where the audit list omits one or more required criteria of the goal.","commonSituations":"New required criteria added after the audit was assembled; audit built from a stale criteria snapshot; optional/required flags misunderstood.","solutions":["Rebuild the audit from the goal's current criteria so every required criterion has a row","If the criterion is genuinely out of scope, mark it not_applicable_user_accepted with notes instead of omitting it","Double-check criterion.required flags when constructing the audit"],"exampleFix":"// before\naudit = [AuditRow(criterion_id=\"c1\", ...)]  # goal also requires c2\nstore.update_status(..., status=\"completed\", audit=audit)\n// after\naudit = [AuditRow(criterion_id=c.criterion_id, ...) for c in store.list_criteria(goal_id) if c.required]\nstore.update_status(..., status=\"completed\", audit=audit)","handlingStrategy":"validation","validationCode":"required = [c.criterion_id for c in store.list_criteria(goal_id) if c.required]\naudit_by_id = {r.criterion_id: r for r in audit}\nmissing = [cid for cid in required if cid not in audit_by_id]\nassert not missing, f\"audit missing: {missing}\"","typeGuard":"def audit_covers_required(store, goal_id: str, audit: list) -> bool:\n    required = {c.criterion_id for c in store.list_criteria(goal_id) if c.required}\n    return required <= {r.criterion_id for r in audit}","tryCatchPattern":"except ValueError as e: if 'missing audit row' in str(e): rebuild audit from current criteria and retry update_status once","preventionTips":["Build the audit programmatically from the store's criteria list","Re-pull criteria right before completion","For out-of-scope criteria use not_applicable rows, not omission"],"tags":["goal-store","completion-audit","validation","python"],"backgroundTag":"schema-validation-failed","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}