{"record":{"id":"1c5f93db8c1b4f45","repo":"xpzouying/xiaohongshu-mcp","slug":"s-1c5f93","errorCode":null,"errorMessage":"等待发布按钮可点击超时: %s","messagePattern":"等待发布按钮可点击超时: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xiaohongshu/publish.go","lineNumber":476,"sourceCode":"\n\tfor time.Since(start) < maxWait {\n\t\tbtn, disabledReason, err := findPublishButton(page)\n\t\tif err != nil {\n\t\t\tslog.Warn(\"查找发布按钮失败，继续等待\", \"error\", err)\n\t\t\ttime.Sleep(interval)\n\t\t\tcontinue\n\t\t}\n\t\tif btn != nil && disabledReason == \"\" {\n\t\t\treturn btn, nil\n\t\t}\n\t\tif disabledReason != \"\" {\n\t\t\tlastDisabledReason = disabledReason\n\t\t}\n\t\ttime.Sleep(interval)\n\t}\n\n\tif lastDisabledReason != \"\" {\n\t\treturn nil, errors.Errorf(\"等待发布按钮可点击超时: %s\", lastDisabledReason)\n\t}\n\treturn nil, errors.New(\"等待发布按钮可点击超时\")\n}\n\nfunc findPublishButton(page *rod.Page) (*publishButton, string, error) {\n\twidgets, err := page.Elements(\"xhs-publish-btn\")\n\tif err != nil {\n\t\treturn nil, \"\", errors.Wrap(err, \"查找新版发布按钮失败\")\n\t}\n\n\tfor _, widget := range widgets {\n\t\tif !isElementVisible(widget) {\n\t\t\tcontinue\n\t\t}\n\n\t\tisPublish, err := widget.Attribute(\"is-publish\")\n\t\tif err != nil {\n\t\t\treturn nil, \"\", errors.Wrap(err, \"读取新版发布按钮 is-publish 属性失败\")","sourceCodeStart":458,"sourceCodeEnd":494,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/publish.go#L458-L494","documentation":"waitForPublishButtonClickable polls for up to 15 seconds for a clickable publish button. If the timeout expires, it raises this error including the last known reason the button was disabled (e.g. '新版发布按钮不可点击'), or a generic timeout when no reason was captured.","triggerScenarios":"The publish form never reaches a state where the button is enabled: required fields (title/content/cover) invalid, the custom widget reports submit-disabled=true persistently, or the button never renders within 15 seconds.","commonSituations":"Uploading a very large video/image so content isn't ready within 15s; Xiaohongshu marks the submit disabled due to form validation (missing cover, forbidden words); slow network keeping the page in a loading state.","solutions":["Complete all required form fields (title, content, cover) before publishing","Increase the wait budget by pre-waiting for uploads to finish before calling Publish","Retry; if caused by slow loading, a retry with less load may succeed","Check the included reason string (after the colon) to identify the specific disabled cause"],"exampleFix":"// before\n// large video still uploading; button stays disabled 15s\nerr := xhs.PublishVideo(...) // 等待发布按钮可点击超时: 新版发布按钮不可点击\n// after\n// wait for upload completion signal before clicking through the library flow\nwaitUploadFinished(page)\nerr := xhs.PublishVideo(...)","handlingStrategy":"retry","validationCode":"// 调用前确保表单必填项齐全且上传已完成\nif title == \"\" || content == \"\" || !uploadFinished {\n    return errors.New(\"发布表单未就绪，发布按钮会保持禁用\")\n}","typeGuard":null,"tryCatchPattern":"err := xhs.Publish(...)\nif err != nil && strings.Contains(err.Error(), \"等待发布按钮可点击超时\") {\n    reason := err.Error() // 冒号后为具体禁用原因\n    // 依据 reason 修复表单后重试\n}","preventionTips":["Fill all required fields (title, content, cover) before publishing","Wait for media uploads to finish before the publish step","Parse the reason after the colon to diagnose the disabled cause","Allow more wall time on slow networks"],"tags":["browser-automation","timeout","form-validation"],"backgroundTag":"publish-button-timeout","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"}