{"record":{"id":"9e511320ca12c650","repo":"xpzouying/xiaohongshu-mcp","slug":"error-9e5113","errorCode":null,"errorMessage":"未找到声明原创按钮","messagePattern":"未找到声明原创按钮","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xiaohongshu/publish.go","lineNumber":1054,"sourceCode":"func confirmOriginalDeclaration(page *rod.Page) error {\n\ttime.Sleep(800 * time.Millisecond) // 技术等待：等确认弹窗渲染\n\n\tif footer, err := findFooterByText(page, \"原创声明须知\"); err != nil {\n\t\tslog.Warn(\"未找到原创声明确认弹窗的 footer\", \"error\", err)\n\t} else if err := checkFooterCheckbox(footer); err != nil {\n\t\tslog.Warn(\"勾选原创声明须知失败\", \"error\", err)\n\t}\n\n\ttime.Sleep(500 * time.Millisecond) // 技术等待：勾选后等\"声明原创\"按钮变可用\n\n\tfooter, err := findFooterByText(page, \"声明原创\")\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"未找到声明原创弹窗\")\n\t}\n\n\tbtn, err := footer.Element(\"button.custom-button\")\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"未找到声明原创按钮\")\n\t}\n\n\tif isButtonDisabled(btn) {\n\t\t// 兜底：按钮仍禁用，可能须知未勾上，再勾一次\n\t\tif err := checkFooterCheckbox(footer); err != nil {\n\t\t\tslog.Warn(\"二次勾选须知失败\", \"error\", err)\n\t\t}\n\t\ttime.Sleep(300 * time.Millisecond)\n\t\tif isButtonDisabled(btn) {\n\t\t\treturn errors.New(\"声明原创按钮仍处于禁用状态\")\n\t\t}\n\t}\n\n\tif err := humanize.Click(btn); err != nil {\n\t\treturn errors.Wrap(err, \"点击声明原创按钮失败\")\n\t}\n\tslog.Info(\"已成功点击声明原创按钮\")\n\ttime.Sleep(300 * time.Millisecond)","sourceCodeStart":1036,"sourceCodeEnd":1072,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/publish.go#L1036-L1072","documentation":"Thrown by confirmOriginalDeclaration when footer.Element(\"button.custom-button\") fails — the 声明原创 dialog footer was found but contains no button.custom-button. The dialog is present but its internal button markup does not match, or the matched footer belongs to a different dialog.","triggerScenarios":"XHS changed the confirm button's class away from custom-button; findFooterByText matched a different dialog whose footer contains 声明原创 text but no such button; the dialog is mid-render so the button has not mounted yet.","commonSituations":"XHS front-end update renaming button classes; multiple stacked dialogs; slow dialog render outpacing the fixed sleeps.","solutions":["Inspect the live dialog DOM (page.HTML()) and update the button selector to current class names.","Use a robust selector: footer.Elements(\"button\") and pick by text content instead of a hard-coded class.","Wait for the button to exist before querying instead of relying on fixed sleeps.","Log the matched footer text to confirm findFooterByText found the intended dialog."],"exampleFix":"// before\nbtn, err := footer.Element(\"button.custom-button\")\n// after\nbtns, err := footer.Elements(\"button\")\nif err != nil {\n\treturn errors.Wrap(err, \"未找到声明原创按钮\")\n}\nvar btn *rod.Element\nfor _, b := range btns {\n\tt, _ := b.Text()\n\tif strings.Contains(t, \"声明原创\") {\n\t\tbtn = b\n\t\tbreak\n\t}\n}\nif btn == nil {\n\treturn errors.New(\"未找到声明原创按钮\")\n}","handlingStrategy":"fallback","validationCode":"ok, err := page.Eval(`() => { const f=[...document.querySelectorAll('div.footer')].find(x=>x.innerText.includes('声明原创')); return !!f && !!f.querySelector('button'); }`)\nif err != nil || !ok.Value.Bool() {\n\treturn fmt.Errorf(\"声明原创弹窗内未找到按钮\")\n}","typeGuard":null,"tryCatchPattern":"if err := setOriginal(page); err != nil {\n\tif strings.Contains(err.Error(), \"未找到声明原创按钮\") {\n\t\thtml, _ := page.HTML()\n\t\tslog.Warn(\"confirm button selector mismatch\", \"htmlLen\", len(html))\n\t}\n\treturn err\n}","preventionTips":["Select buttons by visible text rather than hard-coded class names like custom-button.","Log the matched footer's text to confirm findFooterByText found the right dialog.","Re-verify selectors after each XHS front-end release.","Wait for the dialog to finish rendering before querying its buttons."],"tags":["selector-not-found","go-rod","automation","ui-changed"],"backgroundTag":"element-selector-not-found","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"}