xpzouying/xiaohongshu-mcp · error
未找到评论 %s,它可能不在「评论和@」里或已被清理
Error message
未找到评论 %s,它可能不在「评论和@」里或已被清理
What it means
locate() walks the「评论和@」(mentions) notification tab, matching payload.MessageList entries by comment ID. It scrolls and pages through the list; when the API reports HasMore=false without ever matching the requested commentID, it concludes the comment is not reachable via that tab and returns this error. This is a deliberate, user-facing message — not an internal failure.
Source
Thrown at xiaohongshu/notification_reply.go:123
for range maxRounds {
payload, err := n.readTab(page, TabMentions)
if err != nil {
return nil, 0, err
}
for i, r := range payload.MessageList {
if r.Comment.ID != commentID {
continue
}
if !r.visible() {
return nil, 0, fmt.Errorf("该评论已删除或不可见,不能回复: %s", commentID)
}
return &r, i, nil
}
if !payload.HasMore {
return nil, 0, fmt.Errorf("未找到评论 %s,它可能不在「评论和@」里或已被清理", commentID)
}
if err := page.Mouse.Scroll(0, 800, 5); err != nil {
return nil, 0, fmt.Errorf("滚动查找失败: %w", err)
}
humanize.Delay(ctx, humanize.BetweenScroll)
if err := ctx.Err(); err != nil {
return nil, 0, err
}
}
return nil, 0, fmt.Errorf("翻找 %d 轮仍未定位到评论 %s", maxRounds, commentID)
}
// verifyReplyTarget 用输入框的 placeholder 核对回复对象。
func verifyReplyTarget(input *rod.Element, nickname string) error {
placeholder, err := input.Attribute("placeholder")
if err != nil || placeholder == nil {View on GitHub (pinned to 332d196854)
Solutions
- Verify the commentID is a real comment ID from a NotificationItem.Comment.ID, not a feed or note ID
- Refresh the notification list (re-fetch notifications) and confirm the comment still appears in「评论和@」before replying
- If the comment is known only from a note page, use the note-page reply flow instead of the notification-reply flow
- Handle the error by marking the comment as no-longer-replyable in your data store and skip it
Example fix
// before
_, err := action.Reply(ctx, staleCommentID, "thanks")
// after
items, _ := action.List(ctx, TabMentions) // or readTab equivalent
found := false
for _, it := range items { if it.Comment.ID == staleCommentID { found = true } }
if !found { log.Printf("skip: comment %s no longer in mentions", staleCommentID); return nil } Defensive patterns
Strategy: validation
Validate before calling
// refresh the mentions list and confirm the comment is present before replying
payload, err := readTabMentions() // your own refresh of the notification list
if err != nil { return err }
found := false
for _, m := range payload.MessageList {
if m.Comment.ID == commentID && m.visible() { found = true; break }
}
if !found { return fmt.Errorf("comment %s not currently in mentions; skip reply", commentID) } Type guard
func isReplyable(m NotificationMessage) bool {
return m.Comment.ID != "" && m.visible()
} Prevention
- Store comment IDs together with a timestamp and refuse to reply to comments older than a few days
- Always re-fetch the notification list before replying instead of trusting cached IDs
- Distinguish comment IDs from feed/note IDs at ingestion time
- Treat this error as permanent for that ID — do not retry the same commentID
When it happens
Trigger: Calling NotificationAction.Reply(ctx, commentID, content) (or Like) with a commentID that: (1) never appeared in「评论和@」notifications (e.g. it came from a different feed), (2) was auto-cleaned/expired by the platform's notification retention, (3) is deleted (this error is the fallback after the deleted-check passes the visible list), or (4) sits beyond 20 scroll rounds while HasMore remains true then flips false before it is reached.
Common situations: Reusing a stale commentID stored from a previous session; replying to a comment whose notification XHS already pruned; passing a feed/note ID instead of a comment ID; the notification list ordering changed so the comment falls off before HasMore becomes false.
Related errors
AI-assisted analysis of xpzouying/xiaohongshu-mcp@332d196854 (2026-09-05).
Data as JSON: /api/errors/6d5d013a559e1850.
Report an issue: GitHub.