HKUDS/Vibe-Trading · error · HTTPException

invalid risk_tier: {req.risk_tier}

Error message

invalid risk_tier: {req.risk_tier}

What it means

When creating a session goal, the request's risk_tier string is converted with RiskTier(req.risk_tier); any value not matching a member of the RiskTier enum raises ValueError, which is re-raised as 400 with the offending value shown. This is enum validation, not business-logic rejection (that's the separate live-trading check).

Source

Thrown at agent/src/api/sessions_routes.py:455

        "/sessions/{session_id}/goal",
        response_model=GoalSnapshotResponse,
        status_code=status.HTTP_201_CREATED,
        dependencies=[Depends(require_auth)],
    )
    async def create_session_goal(session_id: str, req: CreateGoalRequest):
        """Create or replace the current finance research goal for a session."""
        _host_validate_path_param(session_id, "session_id")
        svc, _session = _get_existing_session_or_404(session_id)
        from src.goal import RiskTier
        from src.goal.context import default_goal_criteria

        criteria = [item.strip() for item in req.criteria if item.strip()]
        if not criteria:
            criteria = default_goal_criteria()
        try:
            risk_tier = RiskTier(req.risk_tier)
        except ValueError as exc:
            raise HTTPException(status_code=400, detail=f"invalid risk_tier: {req.risk_tier}") from exc
        if risk_tier is RiskTier.LIVE_TRADING_OR_EXECUTION:
            raise HTTPException(status_code=400, detail="live trading or execution goals are not supported")

        goal_store = _get_goal_store()
        try:
            goal = goal_store.replace_goal(
                session_id=session_id,
                objective=req.objective,
                criteria=criteria,
                ui_summary=req.ui_summary,
                source="api",
                protocol=req.protocol,
                risk_tier=risk_tier,
                token_budget=req.token_budget,
                turn_budget=req.turn_budget,
                time_budget_seconds=req.time_budget_seconds,
            )
        except ValueError as exc:

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Use one of the exact RiskTier enum values accepted by the server (inspect the RiskTier enum in agent source or the API schema)
  2. Validate risk_tier on the client before sending (enum membership check)
  3. Upgrade the client to match the server version's enum if values changed
  4. Send the value with exact casing/spelling required by the enum

Example fix

# before
api.create_session_goal(sid, objective="...", risk_tier="high")  # 400

# after
risk_tier="LOW_RISK"  # exact RiskTier member, e.g. one of the enum's defined names
api.create_session_goal(sid, objective="...", risk_tier=risk_tier)
Defensive patterns

Strategy: type-guard

Validate before calling

from agent.goals import RiskTier  # or fetch allowed values from OpenAPI schema
ALLOWED = {t.value for t in RiskTier}
assert req.risk_tier in ALLOWED, f"risk_tier must be one of {sorted(ALLOWED)}"

Type guard

from typing import Literal
RiskTierName = Literal["LOW_RISK", "MEDIUM_RISK", "HIGH_RISK"]  # mirror server enum

def is_valid_risk_tier(v: str) -> TypeGuard[RiskTierName]:
    return v in ("LOW_RISK", "MEDIUM_RISK", "HIGH_RISK")

Try / catch

try:
    goal = api.create_session_goal(sid, payload)
except HTTPError as e:
    if e.response.status_code == 400 and "risk_tier" in e.response.text:
        raise ValueError(f"Bad risk_tier {payload['risk_tier']!r}; allowed: {sorted(ALLOWED)}") from e
    raise

Prevention

When it happens

Trigger: POST /sessions/{id}/goal (or PUT replacing the goal) with risk_tier like 'high', 'LIVE', 'medium-risk', an empty string, or any casing/typo not exactly matching a RiskTier member name/value.

Common situations: Client invents its own tier vocabulary instead of the enum's; casing differences (e.g. 'live_trading_or_execution' vs the canonical form); older clients sending tiers removed in a version change; form fields defaulting to '' when untouched.

Related errors


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