MetaCubeX/mihomo · error · UserNotFound
User not found.
Error message
User not found.
What it means
UserNotFound is raised at mihomo/client.py:93 when api.mihomo.me answers HTTP 404 for the requested UID. It means the UID is syntactically acceptable but the API has no showcase data for it — most often because the player's public battle-record/showcase is hidden or the UID simply doesn't exist. The exception carries the fixed message 'User not found.' (mihomo/errors.py:36) with no extra payload.
Source
Thrown at mihomo/client.py:93
async with aiohttp.ClientSession() as session:
async with session.get(url, params=params) as response:
match response.status:
case 200:
return await response.json(encoding="utf-8")
case 400:
try:
data = await response.json(encoding="utf-8")
except:
raise InvalidParams()
else:
if isinstance(data, dict) and (
detail := data.get("detail")
):
raise InvalidParams(detail)
raise InvalidParams()
case 404:
raise UserNotFound()
case _:
raise HttpRequestError(response.status, str(response.reason))
async def fetch_user(
self,
uid: int,
*,
replace_icon_name_with_url: bool = False,
) -> StarrailInfoParsed:
"""
Fetches user data from the API.
Args:
- uid (`int`): The user ID.
- replace_icon_name_with_url (`bool`): Whether to replace icon names with asset URLs.
Returns:
StarrailInfoParsed: The parsed user data from mihomo API.View on GitHub (pinned to 008b91bfe8)
Solutions
- Double-check the UID — it must be the in-game 9-digit UID shown on the profile, not the HoYoverse account ID.
- Ask the player to enable 'Show character details' / public battle record in game settings, then retry.
- Catch UserNotFound and treat it as a distinct, user-facing condition (unknown player) rather than a generic failure.
- If the UID is definitely valid and public, wait a few minutes — the API caches aggressively — and retry once.
Example fix
// before
data = await client.fetch_user(uid) # raises UserNotFound, crashes app
// after
from mihomo.errors import UserNotFound
try:
data = await client.fetch_user(uid)
except UserNotFound:
return "Player not found — check the UID and enable public battle record." Defensive patterns
Strategy: try-catch
Validate before calling
# Cannot fully prevent: 404 depends on server-side data.
# Cheap pre-check: format-validate the UID.
def looks_like_uid(uid: int | str) -> bool:
return str(uid).isdigit() and len(str(uid)) == 9 Try / catch
from mihomo.errors import UserNotFound, InvalidParams, HttpRequestError
try:
data = await client.fetch_user(uid)
except UserNotFound:
reply("Player not found — check the UID and enable the public battle record.")
except InvalidParams as e:
reply(f"Bad request: {e.message}")
except HttpRequestError as e:
reply(f"API error {e.status}: {e.reason}") Prevention
- Distinguish UserNotFound from generic errors in your handler; it is an expected, user-facing outcome.
- Tell users to enable 'public battle record' in-game before querying their profile.
- Pre-validate UID format to catch typos before spending a request.
- Cache negative results briefly so repeated lookups of a dead UID don't hammer the API.
When it happens
Trigger: Calling fetch_user/fetch_user_v1 with a well-formed 9-digit UID that does not exist; the player has 'Show battle record' / showcase visibility disabled in-game; the UID region is correct in form but the account was deleted or the data cache has no entry.
Common situations: Users copying their account ID instead of the in-game UID; players who never enabled the public showcase (the mihomo API can only serve data when the battle record is public); recently created accounts whose data the API hasn't indexed yet; transposed digits in a hardcoded UID.
Related errors
AI-assisted analysis of MetaCubeX/mihomo@008b91bfe8 (2026-08-27).
Data as JSON: /api/errors/1a5589c7f93d8de6.
Report an issue: GitHub.