{"record":{"id":"9eaf0366b825d5dc","repo":"xpzouying/xiaohongshu-mcp","slug":"s-9eaf03","errorCode":null,"errorMessage":"页面状态里没有分区 %s，可能未登录或页面结构已变化","messagePattern":"页面状态里没有分区 (.+?)，可能未登录或页面结构已变化","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xiaohongshu/notification.go","lineNumber":298,"sourceCode":"\t\treturn r.UserInfo\n\t}\n\treturn r.User\n}\n\n// readTab 读取指定分区的原始数据，字段映射由结构体承担。\nfunc (n *NotificationAction) readTab(page *rod.Page, tab NotificationTab) (*notificationPayload, error) {\n\tres, err := page.Eval(`(tab) => {\n\t\tconst s = window.__INITIAL_STATE__;\n\t\tconst m = s && s.notification && s.notification.notificationMap;\n\t\treturn m && m[tab] ? JSON.stringify(m[tab]) : \"\";\n\t}`, string(tab))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"读取通知列表失败: %w\", err)\n\t}\n\n\traw := res.Value.String()\n\tif raw == \"\" {\n\t\treturn nil, fmt.Errorf(\"页面状态里没有分区 %s，可能未登录或页面结构已变化\", tab)\n\t}\n\n\tvar payload notificationPayload\n\tif err := json.Unmarshal([]byte(raw), &payload); err != nil {\n\t\treturn nil, fmt.Errorf(\"解析通知列表失败: %w\", err)\n\t}\n\treturn &payload, nil\n}\n\n// visible 判断一条通知的内容是否仍然正常可见。\nfunc (r rawNotification) visible() bool {\n\tif r.Comment.ID != \"\" && r.Comment.Illegal.Status != \"\" && r.Comment.Illegal.Status != statusNormal {\n\t\treturn false\n\t}\n\tif r.Item.ID != \"\" && r.Item.Illegal.Status != \"\" && r.Item.Illegal.Status != statusNormal {\n\t\treturn false\n\t}\n\treturn true","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/notification.go#L280-L316","documentation":"readTab 的空值守卫：page.Eval 成功但 notificationMap 中没有请求的 tab 分区（返回空串）：大概率未登录（无通知数据注入）或前端状态结构变化导致分区缺失。","triggerScenarios":"List/locate/likedMatches 调用 readTab 且 notificationMap[tab] 不存在：未登录被重定向、页面未完成水合、小红书改版后 __INITIAL_STATE__ 结构变化、tab 名对应分区在当前账号不可见。","commonSituations":"Cookie 过期导致未登录状态；自动化访问太快页面停留在异常/验证页；前端版本升级把 notificationMap 改名或移动。","solutions":["先调用确认登录态的接口或检查 Cookie 是否有效，重新注入登录态","手动打开 https://www.xiaohongshu.com/notification 检查 __INITIAL_STATE__ 结构","确认传入的 tab 值与 NotificationTab 常量一致","等待页面加载完成（MustWaitLoad + sleep）后重试一次"],"exampleFix":"// before\nraw := res.Value.String()\nif raw == \"\" { return nil, fmt.Errorf(\"页面状态里没有分区 %s，可能未登录或页面结构已变化\", tab) }\n// after\nraw := res.Value.String()\nif raw == \"\" {\n    if !loggedIn(page) { refreshCookies(); page.MustNavigate(notificationURL).MustWaitLoad() }\n    return nil, fmt.Errorf(\"页面状态里没有分区 %s，可能未登录或页面结构已变化\", tab)\n}","handlingStrategy":"fallback","validationCode":"// 调用前检查登录态\ninfo, err := page.Eval(`() => !!window.__INITIAL_STATE__ && !!window.__INITIAL_STATE__.user && window.__INITIAL_STATE__.user.loggedIn`)","typeGuard":null,"tryCatchPattern":"items, err := n.List(ctx)\nif err != nil && strings.Contains(err.Error(), \"可能未登录\") {\n    // 刷新登录态/Cookie 后 fallback 重试\n    reloadCookies()\n    items, err = n.List(ctx)\n}","preventionTips":["定期刷新并校验 Cookie 有效性","调用前先检查页面 URL 未被重定向到登录页","避免高频访问触发异常/验证页","页面加载完成后稍作等待再读取状态"],"tags":["go","rod","login-state","dom-structure-change"],"backgroundTag":"page-state-missing","analyzedSha":"332d196854a9eac0d2b8c2c0e3d0cc43139d724c","analyzedAt":"2026-09-05T22:22:55.988Z","contentChangedAt":"2026-09-05T22:22:55.988Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}