{"record":{"id":"31c0ecb84dbc67fb","repo":"HKUDS/Vibe-Trading","slug":"evidence-limit-must-be-positive","errorCode":null,"errorMessage":"evidence limit must be positive","messagePattern":"evidence limit must be positive","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/goal/store.py","lineNumber":517,"sourceCode":"    @_synchronized\n    def list_claims(self, goal_id: str) -> list[GoalClaim]:\n        \"\"\"Return claims for a goal.\"\"\"\n        rows = self._conn.execute(\n            \"\"\"\n            SELECT * FROM goal_claims\n            WHERE goal_id = ?\n            ORDER BY created_at, claim_id\n            \"\"\",\n            (normalize_required_text(goal_id, \"goal_id\"),),\n        ).fetchall()\n        return [self._claim_from_row(row) for row in rows]\n\n    @_synchronized\n    def list_evidence(self, goal_id: str, limit: int | None = None) -> list[EvidenceRecord]:\n        \"\"\"Return evidence rows for a goal.\"\"\"\n        goal_id = normalize_required_text(goal_id, \"goal_id\")\n        if limit is not None and limit <= 0:\n            raise ValueError(\"evidence limit must be positive\")\n        if limit is not None:\n            rows = self._conn.execute(\n                \"\"\"\n                SELECT * FROM (\n                    SELECT * FROM goal_evidence\n                    WHERE goal_id = ?\n                    ORDER BY created_at DESC, evidence_id DESC\n                    LIMIT ?\n                )\n                ORDER BY created_at, evidence_id\n                \"\"\",\n                (goal_id, limit),\n            ).fetchall()\n            return [self._evidence_from_row(row) for row in rows]\n        rows = self._conn.execute(\n            \"\"\"\n            SELECT * FROM goal_evidence\n            WHERE goal_id = ?","sourceCodeStart":499,"sourceCodeEnd":535,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/goal/store.py#L499-L535","documentation":"list_evidence validates its optional limit argument: if limit is not None it must be > 0, else ValueError('evidence limit must be positive'). The limit backs a SQL TOP/LIMIT clause, and 0 or negative values are treated as caller bugs rather than 'return nothing'.","triggerScenarios":"Calling store.list_evidence(goal_id, limit=0) (a common 'default' from configs) or with a negative limit; get_goal_snapshot forwards a limit it received, so a bad limit there surfaces here.","commonSituations":"Config/UI defaults of 0 intended as 'no limit' — this API uses None for that; pagination math like (page-1)*size producing 0 on page 1 or negatives past the end; env-var parsing yielding 0.","solutions":["Pass None (or omit limit) when you want all evidence rows","Use max(1, limit) if a clamped small limit is acceptable","Fix pagination to guard page >= 1 and size >= 1 before computing the limit","Validate limits at the API boundary with a clear message naming the parameter"],"exampleFix":"# before\nevidence = store.list_evidence(goal_id, limit=0)\n# after\nevidence = store.list_evidence(goal_id, limit=None)","handlingStrategy":"validation","validationCode":"def clean_limit(v):\n    return None if v is None else max(1, int(v))\n\nrows = store.list_evidence(goal_id, limit=clean_limit(limit))","typeGuard":"def is_valid_limit(v) -> bool:\n    return v is None or (isinstance(v, int) and not isinstance(v, bool) and v > 0)","tryCatchPattern":"try:\n    rows = store.list_evidence(goal_id, limit=limit)\nexcept ValueError as e:\n    if 'limit must be positive' in str(e):\n        rows = store.list_evidence(goal_id, limit=None)\n    else:\n        raise","preventionTips":["Use None for 'all rows', not 0","Guard pagination math: page >= 1, size >= 1 before computing limits","Validate limit parameters at the API boundary"],"tags":["validation","goal-store","pagination","positive-integer"],"backgroundTag":"non-positive-numeric-argument","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}