HKUDS/Vibe-Trading · error · StaleGoalError
goal is not available for this session
Error message
goal is not available for this session
What it means
The goal id does not exist, or it belongs to a different session than the session_id supplied. _require_mutable_goal looks up the goal and verifies goal.session_id == session_id before allowing mutation.
Source
Thrown at agent/src/goal/store.py:837
updated = self.get_goal(goal_id)
if updated is None:
raise RuntimeError("usage-updated goal could not be reloaded")
return updated
def _require_mutable_goal(
self,
session_id: str,
goal_id: str,
expected_goal_id: str,
) -> GoalRecord:
if expected_goal_id != goal_id:
raise StaleGoalError("expected_goal_id does not match target goal")
session_id = normalize_required_text(session_id, "session_id")
goal_id = normalize_required_text(goal_id, "goal_id")
goal = self.get_goal(goal_id)
if goal is None or goal.session_id != session_id:
raise StaleGoalError("goal is not available for this session")
if goal.status not in _CURRENT_STATUSES:
raise StaleGoalError(f"goal status {goal.status.value!r} is not mutable")
current = self.get_current_goal(session_id)
if current is None or current.goal_id != goal_id:
raise StaleGoalError("goal is not current for this session")
return goal
@staticmethod
def _verification_status(evidence: EvidenceInput) -> str:
"""Return whether evidence has a traceable local artifact/run source."""
if evidence.artifact_path:
try:
artifact = safe_document_path(evidence.artifact_path)
except ValueError:
artifact = None
if artifact and artifact.is_file():
if GoalStore._artifact_hash_matches(artifact, evidence.artifact_hash):
return "verified"View on GitHub (pinned to 80ffdda44c)
Solutions
- Verify the pair with get_goal(goal_id) and compare .session_id before mutating
- Regenerate/lookup the correct session_id for the goal (e.g. from the session record)
- If the goal is gone, create a new goal instead of mutating the dead id
Example fix
// before
store.append_evidence(session_id="sess-a", goal_id="goal-from-b", ...)
// after
goal = store.get_goal(goal_id)
if goal is None or goal.session_id != session_id:
goal = store.create_goal(session_id=session_id, ...)
store.append_evidence(session_id, goal.goal_id, ...) Defensive patterns
Strategy: validation
Validate before calling
goal = store.get_goal(goal_id)
if goal is None or goal.session_id != session_id:
raise LookupError("goal/session mismatch before mutation") Type guard
def goal_belongs_to_session(goal, session_id: str) -> bool:
return goal is not None and goal.session_id == session_id Try / catch
except StaleGoalError as e: if 'not available' in str(e): re-resolve session/goal pair or create a new goal
Prevention
- Never mix ids across sessions; source both from the same session context
- Log goal.session_id alongside goal_id in traces
- Seed tests with matched session/goal fixtures
When it happens
Trigger: Passing a goal_id from another session to update_goal/append_evidence/update_status/account_usage, or a goal_id that was deleted or never created.
Common situations: Session id regenerated mid-run; ids swapped in logs or fixtures; test using mismatched seeded session/goal pairs.
Related errors
- {field_name} cannot be empty
- at least one goal criterion is required
- expected_goal_id does not match target goal
- goal status {goal.status.value!r} is not mutable
- goal is not current for this session
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/86acff7f9bd52bbb.
Report an issue: GitHub.