{"record":{"id":"e1c322ac82935758","repo":"xpzouying/xiaohongshu-mcp","slug":"error-e1c322","errorCode":null,"errorMessage":"等待发布按钮可点击超时","messagePattern":"等待发布按钮可点击超时","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xiaohongshu/publish.go","lineNumber":478,"sourceCode":"\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 属性失败\")\n\t\t}\n\t\tif isPublish != nil && *isPublish == \"false\" {","sourceCodeStart":460,"sourceCodeEnd":496,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/publish.go#L460-L496","documentation":"waitForPublishButtonClickable polls the publish button (custom element `xhs-publish-btn` or fallback selector) until it is enabled, recording the last reason it was disabled. If the deadline expires it throws this generic timeout, or — if a disable reason was captured (e.g. '上传中', '请填写正文') — the more specific wrapped variant with that reason appended.","triggerScenarios":"clickPublishButton or uploadVideo call it before clicking; the button remains disabled past the deadline because required fields are empty, files are still uploading, or the button selector no longer matches the current XHS page version.","commonSituations":"Missing or too-short description; images/video still uploading (button disabled with a progress state); XHS A/B redesign moving the button out of the polled selector; very slow uploads exceeding the wait interval budget.","solutions":["Read the wrapped reason (errors.Errorf variant) — it names the disable cause; fill the missing field or wait for uploads to finish","Ensure findContentElement/clickAddProductButton etc. completed so required inputs are filled before waiting","Verify the `xhs-publish-btn` custom element still exists on the current XHS publish page version; update findPublishButton selectors if redesigned","Increase the deadline/interval to accommodate slow media uploads on poor networks"],"exampleFix":"// before\nreturn nil, errors.New(\"等待发布按钮可点击超时\")\n// after\nreturn nil, errors.Errorf(\"等待发布按钮可点击超时 (lastDisabledReason=%s)\", lastDisabledReason)","handlingStrategy":"validation","validationCode":"// 发布前自检：必填项与上传是否完成\nif title == \"\" || description == \"\" {\n\treturn errors.New(\"请先填写标题和正文再发布\")\n}\nif !uploadCompleted {\n\treturn errors.New(\"等待图片/视频上传完成后再发布\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always wait for uploads to fully complete before triggering publish","Fill every required field before waitForPublishButtonClickable","Read the wrapped disabled-reason in the error message to identify the missing precondition","Update button selectors when XHS redesigns the publish page"],"tags":["timeout","ui-state","publish-button","xiaohongshu"],"backgroundTag":"publish-button-disabled-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"}