HKUDS/Vibe-Trading · error · ValueError
unknown criterion_id: {criterion_id}
Error message
unknown criterion_id: {criterion_id} What it means
append_evidence referenced a criterion_id that has no row in goal_criteria for that goal. Criteria are declared when the goal is created; evidence must attach to one of them.
Source
Thrown at agent/src/goal/store.py:884
def _artifact_hash_matches(path: Path, expected_hash: str | None) -> bool:
if not expected_hash:
return False
try:
digest = hashlib.sha256(path.read_bytes()).hexdigest()
except OSError:
return False
return digest == expected_hash.lower().removeprefix("sha256:")
def _require_criterion(self, goal_id: str, criterion_id: str) -> GoalCriterion:
row = self._conn.execute(
"""
SELECT * FROM goal_criteria
WHERE goal_id = ? AND criterion_id = ?
""",
(goal_id, criterion_id),
).fetchone()
if row is None:
raise ValueError(f"unknown criterion_id: {criterion_id}")
return self._criterion_from_row(row)
def _require_claim(self, goal_id: str, claim_id: str) -> GoalClaim:
row = self._conn.execute(
"""
SELECT * FROM goal_claims
WHERE goal_id = ? AND claim_id = ?
""",
(goal_id, claim_id),
).fetchone()
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],View on GitHub (pinned to 80ffdda44c)
Solutions
- List the goal's criteria and use an existing criterion_id
- If the criterion is legitimately new, recreate the goal with the updated criteria set
- Add a pre-call validation step mapping evidence to declared criteria
Example fix
// before
store.append_evidence(..., criterion_id="wrong-id")
// after
criteria = {c.criterion_id for c in store.list_criteria(goal_id)}
assert criterion_id in criteria, f"unknown {criterion_id}; have {criteria}"
store.append_evidence(..., criterion_id=criterion_id) Defensive patterns
Strategy: validation
Validate before calling
known = {c.criterion_id for c in store.list_criteria(goal_id)}
if criterion_id not in known:
raise KeyError(f"criterion {criterion_id} not in {sorted(known)}") Type guard
def criterion_exists(store, goal_id: str, criterion_id: str) -> bool:
return any(c.criterion_id == criterion_id for c in store.list_criteria(goal_id)) Try / catch
except ValueError as e: if str(e).startswith('unknown criterion_id'): list criteria and re-map or fail with context Prevention
- Derive criterion ids from the created goal's criteria, never hardcode
- Regenerate goal fixtures when criteria templates change
- Validate ids at the boundary between LLM output and store calls
When it happens
Trigger: Calling append_evidence with a criterion_id that is misspelled, belongs to another goal, or was removed/never added to this goal's criteria.
Common situations: Hardcoded criterion ids in tests; criteria template changed between goal creation and evidence append; id copy-paste errors.
Related errors
- unknown claim_id: {claim_id}
- {field_name} cannot be empty
- at least one goal criterion is required
- expected_goal_id does not match target goal
- goal is not available for this session
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/bc2c67780931575b.
Report an issue: GitHub.