xpzouying/xiaohongshu-mcp · warning
读不到回复框提示文字,无法确认回复对象,已中止
Error message
读不到回复框提示文字,无法确认回复对象,已中止
What it means
verifyReplyTarget() reads the reply textarea's placeholder attribute to confirm the reply targets the expected nickname. If rod cannot read the attribute at all (err != nil) or the attribute is absent (nil), it aborts rather than risk replying to the wrong person. This is a safety stop — the library refuses to proceed without identity confirmation.
Source
Thrown at xiaohongshu/notification_reply.go:142
}
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 {
return fmt.Errorf("读不到回复框提示文字,无法确认回复对象,已中止")
}
if nickname != "" && !strings.Contains(*placeholder, nickname) {
return fmt.Errorf("回复对象不符:期望 %q,实际提示为 %q,已中止", nickname, *placeholder)
}
return nil
}
// waitReplyAccepted 等待回复提交完成。
func waitReplyAccepted(item *rod.Element, timeout time.Duration) error {
deadline := time.Now().Add(timeout)
for time.Now().Before(deadline) {
has, _, err := item.Has(`textarea.comment-input`)
if err == nil && !has {
return nil
}
time.Sleep(300 * time.Millisecond)
}
return fmt.Errorf("回复未确认成功:发送后输入框仍未收起(可能被限制或发送失败)")View on GitHub (pinned to 332d196854)
Solutions
- Check whether XHS changed the reply-input DOM (inspect textarea.comment-input for placeholder vs aria-label / data-* attributes) and update the selector/attribute used
- Re-fetch the element immediately before reading the attribute to avoid a detached node
- Add a short wait for the input's attributes to hydrate before verifying
- If XHS removed placeholders permanently, verify identity via the adjacent user-name element instead
Example fix
// before
placeholder, err := input.Attribute("placeholder")
if err != nil || placeholder == nil { return err }
// after
ph, err := input.Attribute("placeholder")
if err != nil || ph == nil {
ph, err = input.Attribute("aria-label") // fallback attr after XHS UI change
if err != nil || ph == nil { return err }
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check the input element exists and has identification attributes before Reply
item := items[index]
input, err := item.Element(`textarea.comment-input`)
if err != nil { return fmt.Errorf("reply input missing: %w", err) }
ph, _ := input.Attribute("placeholder")
label, _ := input.Attribute("aria-label")
if ph == nil && label == nil { return fmt.Errorf("input has no identifying attributes; abort") } Try / catch
if _, err := action.Reply(ctx, commentID, content); err != nil {
if strings.Contains(err.Error(), "读不到回复框提示文字") {
log.Printf("cannot verify reply target (UI change?) for %s — skipping, NOT retrying blind", commentID)
return nil // treat as aborted-by-safety-check
}
return err
} Prevention
- Never disable or bypass verifyReplyTarget — it prevents wrong-thread replies
- After XHS frontend deploys, smoke-test one reply before batch runs
- Keep the placeholder/aria-label selector logic in one place for quick updates
When it happens
Trigger: Calling Reply when the comment-input textarea has no placeholder attribute (XHS UI change, locale rendering variant, or the input element was captured before the panel finished rendering), or rod's Attribute call fails due to a stale/detached element.
Common situations: A Xiaohongshu frontend update renaming/removing the placeholder attribute; page in a different state where the input exists but is not hydrated; grabbing the element from the wrong item index; detached element after a re-render between click and attribute read.
Related errors
AI-assisted analysis of xpzouying/xiaohongshu-mcp@332d196854 (2026-09-05).
Data as JSON: /api/errors/5f3a1b711ef3db84.
Report an issue: GitHub.