{"record":{"id":"e925ebe384b8c5b1","repo":"xpzouying/xiaohongshu-mcp","slug":"error-e925eb","errorCode":null,"errorMessage":"回复未确认成功：发送后输入框仍未收起（可能被限制或发送失败）","messagePattern":"回复未确认成功：发送后输入框仍未收起（可能被限制或发送失败）","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xiaohongshu/notification_reply.go","lineNumber":160,"sourceCode":"\t\treturn fmt.Errorf(\"读不到回复框提示文字，无法确认回复对象，已中止\")\n\t}\n\tif nickname != \"\" && !strings.Contains(*placeholder, nickname) {\n\t\treturn fmt.Errorf(\"回复对象不符：期望 %q，实际提示为 %q，已中止\", nickname, *placeholder)\n\t}\n\treturn nil\n}\n\n// waitReplyAccepted 等待回复提交完成。\nfunc waitReplyAccepted(item *rod.Element, timeout time.Duration) error {\n\tdeadline := time.Now().Add(timeout)\n\tfor time.Now().Before(deadline) {\n\t\thas, _, err := item.Has(`textarea.comment-input`)\n\t\tif err == nil && !has {\n\t\t\treturn nil\n\t\t}\n\t\ttime.Sleep(300 * time.Millisecond)\n\t}\n\treturn fmt.Errorf(\"回复未确认成功：发送后输入框仍未收起（可能被限制或发送失败）\")\n}\n","sourceCodeStart":142,"sourceCodeEnd":162,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/notification_reply.go#L142-L162","documentation":"After clicking the submit button, waitReplyAccepted() polls for up to 8s for the textarea.comment-input to disappear from the item, which is how XHS signals a successful reply. If the input is still present after the timeout, the reply was not accepted — possibly rate-limited, content rejected, or a silent send failure.","triggerScenarios":"Reply() submit click succeeded but: XHS rate-limited the account (frequent replies), the content triggered sensitive-word filtering, the click landed but the form failed client-side validation, or the reply succeeded but the input stays open due to a UI change.","commonSituations":"Burst-replying to many comments in a short window; replying with links or banned words; account in a restricted state (shadow-ban on comments); recent XHS UI update that keeps the input open after success.","solutions":["Slow down: add longer humanize delays / spacing between replies and reduce daily reply volume","Manually test one reply in the browser to see if XHS shows an error toast or rate-limit message","Check whether the UI changed (input no longer closes on success) and update the success detection (e.g. watch for a new reply node in DOM instead of input closing)","If rate-limited, wait (hours/day) before retrying; retrying immediately worsens restrictions"],"exampleFix":"// before\nhas, _, err := item.Has(`textarea.comment-input`)\nif err == nil && !has { return nil }\n// after\n// success = input closed OR a new reply node appeared under the item\nif has, _, _ := item.Has(`textarea.comment-input`); !has { return nil }\nif ok, _, _ := item.Has(`div.comment-item .reply-list`); ok { return nil }","handlingStrategy":"try-catch","validationCode":"// pace replies beforehand to avoid rate limits\nif time.Since(lastReplyAt) < 30*time.Second { return fmt.Errorf(\"throttle: wait before next reply\") }","typeGuard":null,"tryCatchPattern":"_, err := action.Reply(ctx, commentID, content)\nif err != nil && strings.Contains(err.Error(), \"回复未确认成功\") {\n    // do NOT immediately retry — likely rate-limit or content rejection\n    log.Printf(\"reply %s unconfirmed; backing off\", commentID)\n    backoffTimer.Reset(10 * time.Minute)\n    return err\n}","preventionTips":["Throttle reply volume (e.g. ≥30s gap, daily caps)","Avoid links/sensitive words in reply content","Manually verify in a real browser what the post-submit UI looks like after XHS updates","Treat unconfirmed ≠ failed: the reply may have gone through; check via a fresh fetch before re-sending to avoid duplicates"],"tags":["browser-automation","go","rate-limit","xiaohongshu"],"backgroundTag":"reply-submit-not-confirmed","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"}