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

  1. Trim user_id on the client before sending and ensure it is a real identifier.
  2. If you control the API and want whitespace-only to become a normal 400, validate before model construction.
  3. 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

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.