datawhalechina/hello-agents · error · HTTPException

该 run 不属于此 user_id

Error message

该 run 不属于此 user_id

What it means

HTTP 403 raised by POST /diet/reflect when the run exists but belongs to a different user (row['user_id'] != body.user_id). This is an ownership check preventing one user from writing reflect feedback onto another user's diet run.

Source

Thrown at Co-creation-projects/Shawnxyxy-HealthRecordAgent/backend/api/routes/diet.py:93

    每阶段最多 2 次尝试,失败则降级并写入 `errors` / `degraded`。
    仍落库 `diet_runs`,并读取 Reflect 记忆。
    """
    svc = DietRecommendService()
    ctx = body.context.model_dump()
    result = await svc.run(body.user_id, ctx)
    return result


@router.post("/diet/reflect")
async def diet_reflect(body: DietReflectRequest):
    """
    Reflect:用户反馈是否执行及原因,写入 diet_reflect;下次 recommend 自动读取。
    """
    row = get_diet_run(body.diet_run_id)
    if not row:
        raise HTTPException(status_code=404, detail="diet_run_id 不存在")
    if row.get("user_id") != body.user_id:
        raise HTTPException(status_code=403, detail="该 run 不属于此 user_id")

    rc = body.reason_code
    if body.followed and rc is None:
        rc = "executed_ok"

    rid = insert_diet_reflect(
        user_id=body.user_id,
        diet_run_id=body.diet_run_id,
        followed=body.followed,
        reason_code=rc,
        reason_detail=body.reason_detail,
    )
    asyncio.create_task(asyncio.to_thread(index_reflect_event, rid))
    return {
        "ok": True,
        "reflect_id": rid,
        "user_id": body.user_id,
        "diet_run_id": body.diet_run_id,

View on GitHub (pinned to 606a07d341)

Solutions

  1. Use the exact same user_id that created the run (re-check it via GET /diet/runs/{run_id} which returns the owning user_id).
  2. Ensure consistent trimming/normalization of user_id on the client.
  3. If genuinely cross-user access is intended, that is not supported by design — create a new run for the second user.

Example fix

# before
# run created with user_id='alice'
requests.post(f"{base}/diet/reflect", json={"user_id": "bob", "diet_run_id": rid, "followed": False})  # 403

# after
requests.post(f"{base}/diet/reflect", json={"user_id": "alice", "diet_run_id": rid, "followed": False})
Defensive patterns

Strategy: validation

Validate before calling

row = requests.get(f"{base}/diet/runs/{diet_run_id}").json()
if row.get("user_id") != my_user_id:
    raise PermissionError("this run belongs to another user; fetch your own run")

Try / catch

try:
    r = requests.post(f"{base}/diet/reflect", json=payload)
except HTTPError as e:
    if e.response.status_code == 403:
        # ownership mismatch: correct user_id, never retry with same pair
        ...

Prevention

When it happens

Trigger: POST /diet/reflect with a valid diet_run_id but a user_id that differs from the one used when the run was created (including differences from whitespace or case).

Common situations: Testing with one user_id in /diet/recommend and another in /diet/reflect; logged-out client defaulting to a placeholder id; user_id normalization mismatch between the two calls.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/b663925f98d8bcce. Report an issue: GitHub.