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
- Validate/trim user_id in the client before building the URL.
- Send an actual identifier; a whitespace user_id is never meaningful.
- 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
- Validate and trim path parameters before URL construction.
- URL-encode path segments with urllib.parse.quote to avoid %20 ambiguity.
- Centralize URL building for diet endpoints in one helper.
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.