{"record":{"id":"dcad4d7040f58ade","repo":"NanmiCoder/MediaCrawler","slug":"creator-api-response-does-not-contain-user-info","errorCode":null,"errorMessage":"Creator API response does not contain user info: {api_data}","messagePattern":"Creator API response does not contain user info: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"media_platform/tieba/help.py","lineNumber":228,"sourceCode":"                note_url=note_detail.note_url,\n                creator_hash=anonymize_user_id(self._api_user_link(user)),\n                user_nickname=mask_nickname(user.get(\"name_show\") or user.get(\"name\") or \"\"),\n                tieba_id=tieba_id,\n                tieba_name=tieba_name,\n                tieba_link=tieba_link,\n                publish_time=utils.get_time_str_from_unix_time(item.get(\"time\") or 0),\n                note_id=note_detail.note_id,\n            )\n            result.append(comment)\n        return result\n\n    def extract_creator_info_from_api(self, api_data: Dict) -> TiebaCreator:\n        \"\"\"\n        Extract Tieba creator information from current PC creator JSON API.\n        \"\"\"\n        user = api_data.get(\"data\", {}).get(\"user\", {})\n        if not user:\n            raise ValueError(f\"Creator API response does not contain user info: {api_data}\")\n\n        # 教学版：创作者个人资料不再落库，仅保留匿名哈希与脱敏昵称作内存对象。\n        return TiebaCreator(\n            creator_hash=anonymize_user_id(str(user.get(\"id\", \"\"))),\n            user_nickname=mask_nickname(str(user.get(\"name_show\") or user.get(\"name\") or \"\")),\n            follows=int(user.get(\"concern_num\") or 0),\n            fans=int(user.get(\"fans_num\") or 0),\n            registration_duration=str(user.get(\"tb_age\", \"\")),\n        )\n\n    @staticmethod\n    def extract_creator_thread_id_list_from_api(api_data: Dict) -> List[str]:\n        \"\"\"\n        Extract creator thread ids from current PC creator feed JSON API.\n        \"\"\"\n        thread_ids: List[str] = []\n        for item in api_data.get(\"data\", {}).get(\"list\", []):\n            thread_info = item.get(\"thread_info\") or {}","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/NanmiCoder/MediaCrawler/blob/d6f7c5bb906b6dac40ddf343ef9e26438a3de092/media_platform/tieba/help.py#L210-L246","documentation":"Raised by TiebaExtractor.extract_creator_info_from_api (media_platform/tieba/help.py:228) as ValueError when the /c/u/pc/homeSidebarRight response has no data.user object. The extractor navigates api_data.get('data', {}).get('user', {}) and treats an empty result as a broken/expired session rather than producing an empty creator. It usually means the API responded with an error envelope (or empty data) because cookies expired or the portrait is invalid, not that the user has no profile.","triggerScenarios":"get_creator_info_by_url successfully fetching JSON whose 'data' or 'data.user' key is missing — e.g. error envelope {error:...}, expired-cookie response, or a portrait that no longer resolves to an account.","commonSituations":"Creator crawl running on stale cookies after a long session; deleted/renamed accounts; Tieba changing the homeSidebarRight response schema so the user field moved.","solutions":["Re-login to refresh cookies and retry the creator info fetch","Log the full api_data payload to see whether it is an auth error envelope or a schema change","If the schema changed (field renamed/moved), update extract_creator_info_from_api to read the new path"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"user = api_data.get(\"data\", {}).get(\"user\")\nif not user:\n    raise ValueError(\"creator API response missing data.user — likely expired cookies\")","typeGuard":"def api_has_creator_user(api_data: dict) -> bool:\n    return bool(isinstance(api_data, dict) and api_data.get(\"data\", {}).get(\"user\"))","tryCatchPattern":"try:\n    creator = extractor.extract_creator_info_from_api(api_data)\nexcept ValueError as e:\n    if \"does not contain user info\" in str(e):\n        await relogin_and_retry(client)  # expired session is the usual cause\n    raise","preventionTips":["Check for data.user before calling the extractor when handling raw API payloads","Refresh cookies on schedule during long creator crawls","Log api_data shape changes to catch Tieba schema drift early"],"tags":["tieba","api-schema","creator","validation","auth"],"backgroundTag":null,"analyzedSha":"d6f7c5bb906b6dac40ddf343ef9e26438a3de092","analyzedAt":"2026-08-15T01:39:07.505Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}