{"record":{"id":"40939cbc72497d8a","repo":"xpzouying/xiaohongshu-mcp","slug":"s-commentid-s-userid-s","errorCode":null,"errorMessage":"评论区过大，%s 内未找到目标评论 (commentID: %s, userID: %s)","messagePattern":"评论区过大，(.+?) 内未找到目标评论 \\(commentID: (.+?), userID: (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"xiaohongshu/comment_feed.go","lineNumber":210,"sourceCode":"\n// findCommentElement 滚动查找指定评论：优先按 commentID 命中，否则按 userID 匹配。\n// 二级评论折叠在「展开 N 条回复」后面，未展开时不在 DOM 里，因此查找过程中要展开。\nfunc findCommentElement(ctx context.Context, page *rod.Page, commentID, userID string) (*rod.Element, error) {\n\tlogrus.Infof(\"开始查找评论 - commentID: %s, userID: %s\", commentID, userID)\n\n\tscrollToCommentsArea(page)\n\thumanize.Delay(ctx, humanize.BetweenScroll)\n\n\tlastCommentCount := 0\n\tstagnantChecks := 0\n\texpandRounds := 0\n\tdeadline := time.Now().Add(maxSearchDuration)\n\n\t// attempt 只数下滚，展开不计入，由 deadline 收口。\n\tfor attempt := 0; attempt < maxSearchScrolls; {\n\t\tif time.Now().After(deadline) {\n\t\t\tlogrus.Warnf(\"查找超过 %s，停止\", maxSearchDuration)\n\t\t\treturn nil, fmt.Errorf(\"评论区过大，%s 内未找到目标评论 (commentID: %s, userID: %s)\",\n\t\t\t\tmaxSearchDuration, commentID, userID)\n\t\t}\n\n\t\t// 1. 先查已渲染的评论\n\t\tif el := lookupComment(page, commentID, userID); el != nil {\n\t\t\tlogrus.Infof(\"✓ 找到目标评论（下滚 %d 次）\", attempt)\n\t\t\treturn el, nil\n\t\t}\n\n\t\t// 2. 展开视野里的楼中楼后再查一次\n\t\tif expandRounds < maxExpandRounds {\n\t\t\tif expanded := expandNearbyReplies(ctx, page); expanded > 0 {\n\t\t\t\texpandRounds++\n\t\t\t\thumanize.Delay(ctx, humanize.Reading)\n\n\t\t\t\tif el := lookupComment(page, commentID, userID); el != nil {\n\t\t\t\t\tlogrus.Infof(\"✓ 展开楼中楼后找到目标评论（下滚 %d 次）\", attempt)\n\t\t\t\t\treturn el, nil","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/comment_feed.go#L192-L228","documentation":"findCommentElement 的超时收口：滚动搜索达到 maxSearchDuration 时限仍未命中目标评论，但评论区条目数仍在增长（过大），说明评论太多在时限内翻不完，而非评论不存在。","triggerScenarios":"调用 ReplyToComment 时目标评论在很长的评论区深处，滚动查找超过 maxSearchDuration 仍未出现：评论数极多、懒加载慢、或目标评论实际已被删除/不可见。","commonSituations":"给热门帖子（数千条评论）的旧评论回复；commentID 对应的评论已被作者删除或被平台隐藏；弱网下懒加载跟不上滚动节奏，白白耗尽时间预算。","solutions":["确认目标 commentID/userID 对应的评论仍存在（在浏览器手动打开该 feed 查找）","调大 maxSearchDuration 以适配超长评论区","评论很旧/很深时考虑放弃或改用其他触达路径，而非长时间滚动","检查网络状况，弱网下懒加载跟不上滚动会耗尽时间预算"],"exampleFix":"// 调用方处理（库内 deadline 为固定预算）\nerr := action.ReplyToComment(ctx, feedID, token, commentID, userID, content)\nif err != nil && strings.Contains(err.Error(), \"评论区过大\") {\n    log.Warnf(\"评论 %s 在深评论区未找到，安排低峰重试\", commentID)\n    scheduleRetryWithBackoff(feedID, commentID, userID, content)\n    return\n}","handlingStrategy":"retry","validationCode":"if commentID == \"\" && userID == \"\" {\n    return errors.New(\"commentID 与 userID 均为空，无法定位目标评论\")\n}","typeGuard":null,"tryCatchPattern":"err := action.ReplyToComment(ctx, feedID, token, commentID, userID, content)\nif err != nil {\n    if strings.Contains(err.Error(), \"评论区过大\") {\n        // 时间预算耗尽：安排一次低峰重试后放弃\n        scheduleRetryWithBackoff(feedID, commentID, userID, content)\n        return\n    }\n    return err\n}","preventionTips":["优先对近期/靠前的评论回复，避免在数千条评论的帖子里翻找旧评论","回复前确认 commentID 来自较新的抓取数据，减少评论已被删除的概率","对热门帖子设置预期：深评论区查找天然耗时，做好重试/放弃策略","保持网络稳定，弱网会显著降低滚动查找成功率"],"tags":["scroll-search","timeout","comment-lookup","lazy-loading"],"backgroundTag":"comment-not-found-in-feed","analyzedSha":"332d196854a9eac0d2b8c2c0e3d0cc43139d724c","analyzedAt":"2026-09-05T22:22:55.988Z","contentChangedAt":"2026-09-05T22:22:55.988Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}