datawhalechina/hello-agents · warning · ValueError
user_id 不能为空
Error message
user_id 不能为空
What it means
Pydantic field_validator error on the DietRecommendRequest model. The user_id field must be 1-256 chars, and after stripping whitespace it must be non-empty. A value of only whitespace (e.g. " ") passes min_length=1 but fails this validator, producing a 422 response from FastAPI.
Source
Thrown at Co-creation-projects/Shawnxyxy-HealthRecordAgent/backend/api/routes/diet.py:46
default_factory=lambda: ["convenience_store", "delivery"],
description="可购买渠道标签",
)
activity_context: str = Field(default="", max_length=2000, description="运动/睡眠等上下文")
free_notes: str = Field(
default="", max_length=2000, description="额外说明(如只有便利店)"
)
class DietRecommendRequest(BaseModel):
user_id: str = Field(..., min_length=1, max_length=256)
context: DietContext
@field_validator("user_id")
@classmethod
def strip_uid(cls, v: str) -> str:
v = v.strip()
if not v:
raise ValueError("user_id 不能为空")
return v
class DietReplayRequest(BaseModel):
"""可选:传入 user_id 时必须与 run 一致,防止误重放。"""
user_id: Optional[str] = Field(default=None, max_length=256)
class DietReflectRequest(BaseModel):
user_id: str = Field(..., min_length=1, max_length=256)
diet_run_id: str = Field(..., min_length=8, max_length=64)
followed: bool = Field(..., description="是否按上次推荐执行")
reason_code: Optional[
Literal["cant_buy", "too_late", "dont_want", "executed_ok", "other"]
] = Field(default=None, description="未执行或总结原因类型")
reason_detail: Optional[str] = Field(default=None, max_length=2000)
View on GitHub (pinned to 606a07d341)
Solutions
- Trim user_id on the client before sending and ensure it is a real identifier.
- If you control the API and want whitespace-only to become a normal 400, validate before model construction.
- Check the 422 response body: it names the field (user_id) and this message.
Example fix
# before
requests.post(url, json={"user_id": " ", "context": ctx}) # 422
# after
uid = "u123".strip()
assert uid
requests.post(url, json={"user_id": uid, "context": ctx}) Defensive patterns
Strategy: validation
Validate before calling
uid = user_id.strip() if isinstance(user_id, str) else ""
if not uid:
raise ValueError("user_id must be a non-empty trimmed string")
body = {"user_id": uid, "context": ctx} Type guard
def is_valid_user_id(v) -> bool:
return isinstance(v, str) and 1 <= len(v.strip()) <= 256 Prevention
- Trim all user-provided identifiers at the client boundary.
- Add shared request DTOs/types so both frontend and backend apply the same rule.
- Treat FastAPI 422 bodies as validation feedback: they name the exact field.
When it happens
Trigger: POST /diet/recommend with user_id set to a whitespace-only or empty string. The endpoint returns HTTP 422 with the validator message in the response body.
Common situations: Frontend sending an untrimmed form field; copy-paste user IDs containing only spaces; test fixtures using placeholder strings like ' '.
Related errors
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/735983f908e6f35a.
Report an issue: GitHub.