HKUDS/DeepTutor · error · ValueError
Avatar must be empty or 'icon
Error message
Avatar must be empty or 'icon:<name>:<color>'
What it means
Raised by UpdateProfileRequest.avatar_valid when a non-empty avatar string does not match the icon marker pattern ^icon:[a-z0-9-]{1,32}:[a-z0-9-]{1,32}$. Only the empty string (reset) or an 'icon:<name>:<color>' marker is accepted via PUT /profile; uploaded-image markers are owned by the upload endpoint.
Solutions
- Send either '' to clear the avatar or an icon marker in icon:<name>:<color> form
- Use lowercase name/color slugs matching the regex
- For image avatars, use the PUT /profile/avatar upload endpoint instead
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at deeptutor/api/routers/auth.py:180 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/ffa9b8e5933fdae4.
Report an issue: GitHub.
Appendix: source
Thrown at deeptutor/api/routers/auth.py:180
_ICON_MARKER_RE = re.compile(r"^icon:[a-z0-9-]{1,32}:[a-z0-9-]{1,32}$")
# User ids are generated as "u_<uuid hex>" (plus the "local-admin" /
# "env-admin" sentinels); reject anything else before it reaches the
# filesystem layer.
_USER_ID_RE = re.compile(r"^[A-Za-z0-9_-]{1,64}$")
class UpdateProfileRequest(BaseModel):
"""Payload for the PUT /profile endpoint."""
avatar: str
@field_validator("avatar")
@classmethod
def avatar_valid(cls, v: str) -> str:
v = v.strip()
if v and not _ICON_MARKER_RE.match(v):
raise ValueError("Avatar must be empty or 'icon:<name>:<color>'")
return v
# ---------------------------------------------------------------------------
# Shared helper — extract token from cookie or Bearer header
# ---------------------------------------------------------------------------
def _bearer_token_from_header(authorization: str | None) -> str | None:
"""Parse ``Authorization: Bearer <token>`` without using ``HTTPBearer``.
``HTTPBearer`` is a class-based dependency whose ``__call__`` is annotated
``request: Request``. FastAPI doesn't inject a Request into WebSocket
dependency resolution, which makes ``HTTPBearer`` raise ``TypeError`` the
moment a router with this dep mounts a WS endpoint. Doing the parse by
hand keeps ``require_auth`` HTTP/WS-symmetric.
"""
if not authorization:View on GitHub (pinned to 3e82f13042)