datawhalechina/hello-agents · warning · HTTPException

user_id 无效

Error message

user_id 无效

What it means

HTTP 400 raised by GET /diet/users/{user_id}/runs when the path parameter, after .strip(), is empty. Because the route itself captures any non-empty path segment, in practice this fires only for URLs where the segment collapses to whitespace (e.g. '%20'), since a truly empty segment would not match the route.

Source

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

        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,
    }


@router.get("/diet/users/{user_id}/runs")
async def diet_runs(user_id: str, limit: int = 20):
    uid = user_id.strip()
    if not uid:
        raise HTTPException(status_code=400, detail="user_id 无效")
    return {"user_id": uid, "items": list_diet_runs_for_user(uid, limit=limit)}


@router.get("/diet/users/{user_id}/reflect_history")
async def diet_reflect_history(user_id: str, limit: int = 20):
    uid = user_id.strip()
    if not uid:
        raise HTTPException(status_code=400, detail="user_id 无效")
    return {"user_id": uid, "items": list_recent_diet_reflect(uid, limit=limit)}


@router.get("/diet/runs/{run_id}")
async def diet_run_detail(run_id: str):
    row = get_diet_run(run_id.strip())
    if not row:
        raise HTTPException(status_code=404, detail="未找到该饮食推荐 run")
    return row

View on GitHub (pinned to 606a07d341)

Solutions

  1. Validate/trim user_id in the client before building the URL.
  2. Send an actual identifier; a whitespace user_id is never meaningful.
  3. Check for URL-encoding issues (%20) if you believe the id is non-empty.

Example fix

# before
uid = '   '
requests.get(f'{base}/diet/users/{uid}/runs')  # 400

# after
uid = current_user_id.strip()
if not uid:
    raise ValueError('user_id required')
requests.get(f'{base}/diet/users/{uid}/runs')
Defensive patterns

Strategy: validation

Validate before calling

uid = user_id.strip()
if not uid:
    raise ValueError("user_id required")
url = f"{base}/diet/users/{quote(uid)}/runs"

Type guard

def is_valid_path_user_id(v: str) -> bool:
    return isinstance(v, str) and bool(v.strip())

Prevention

When it happens

Trigger: GET /diet/users/%20/rununs (URL-encoded space as user_id), or programmatic clients interpolating an unvalidated variable into the path.

Common situations: Client-side string interpolation of an empty/spaces variable into the URL template; manual curl with quotes around a space.

Related errors


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