{"record":{"id":"284eb09b5380e2c2","repo":"xpzouying/xiaohongshu-mcp","slug":"aria-disabled","errorCode":null,"errorMessage":"读取旧版发布按钮 aria-disabled 属性失败","messagePattern":"读取旧版发布按钮 aria-disabled 属性失败","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xiaohongshu/publish.go","lineNumber":528,"sourceCode":"\n\toldButtons, err := page.Elements(\".publish-page-publish-btn button.bg-red\")\n\tif err != nil {\n\t\treturn nil, \"\", errors.Wrap(err, \"查找旧版发布按钮失败\")\n\t}\n\n\tfor _, oldButton := range oldButtons {\n\t\tif !isElementVisible(oldButton) {\n\t\t\tcontinue\n\t\t}\n\n\t\tif disabled, err := oldButton.Attribute(\"disabled\"); err != nil {\n\t\t\treturn nil, \"\", errors.Wrap(err, \"读取旧版发布按钮 disabled 属性失败\")\n\t\t} else if disabled != nil {\n\t\t\treturn &publishButton{elem: oldButton}, \"旧版发布按钮 disabled\", nil\n\t\t}\n\n\t\tif ariaDisabled, err := oldButton.Attribute(\"aria-disabled\"); err != nil {\n\t\t\treturn nil, \"\", errors.Wrap(err, \"读取旧版发布按钮 aria-disabled 属性失败\")\n\t\t} else if ariaDisabled != nil && *ariaDisabled == \"true\" {\n\t\t\treturn &publishButton{elem: oldButton}, \"旧版发布按钮 aria-disabled=true\", nil\n\t\t}\n\n\t\tif cls, err := oldButton.Attribute(\"class\"); err != nil {\n\t\t\treturn nil, \"\", errors.Wrap(err, \"读取旧版发布按钮 class 属性失败\")\n\t\t} else if cls != nil && hasExactClass(*cls, \"disabled\") {\n\t\t\treturn &publishButton{elem: oldButton}, \"旧版发布按钮包含 disabled class\", nil\n\t\t}\n\n\t\treturn &publishButton{elem: oldButton}, \"\", nil\n\t}\n\n\treturn nil, \"\", nil\n}\n\nfunc clickPublishWidget(page *rod.Page, widget *rod.Element) error {\n\tif err := widget.ScrollIntoView(); err != nil {","sourceCodeStart":510,"sourceCodeEnd":546,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/publish.go#L510-L546","documentation":"Same family as the `disabled` read failure: findPublishButton wraps the error from Element.Attribute(\"aria-disabled\") on a visible legacy publish button. The CDP attribute read itself failed — the button state is unknown, not aria-disabled. The library cannot proceed with its clickability classification, so it aborts.","triggerScenarios":"Element detached between the successful `disabled` read and the `aria-disabled` read (page re-render in between); tab closed or browser crashed during the polling loop; CDP websocket error.","commonSituations":"Publish page re-mounts its button list asynchronously; automation runs against an old-version page that hot-reloads in dev; connection loss to headless Chrome under memory pressure.","solutions":["Retry the wait/click flow — the polling loop re-queries elements so a detached node is usually transient","Add WaitDOMStable/WaitStable before invoking waitForPublishButtonClickable to avoid reading attributes mid-mutation","Verify the Chrome target is still connected (check rod errors / re-launch browser on failure)","Pin/upgrade the rod dependency; some Attribute races were fixed upstream"],"exampleFix":"// before\nbtn, reason, err := findPublishButton(page)\n// after\n_ = page.WaitStable(300 * time.Millisecond)\nbtn, reason, err := findPublishButton(page)","handlingStrategy":"retry","validationCode":"if err := page.WaitDOMStable(time.Second, 0.1); err != nil { return err }\nif _, err := page.Elements(\".publish-page-publish-btn button.bg-red\"); err != nil { return err }","typeGuard":"func canReadAttributes(e *rod.Element) bool {\n    if e == nil { return false }\n    _, err := e.Attribute(\"class\")\n    return err == nil\n}","tryCatchPattern":"btn, reason, err := waitForPublishButtonClickable(page)\nif err != nil && strings.Contains(err.Error(), \"aria-disabled 属性失败\") {\n    time.Sleep(500 * time.Millisecond)\n    btn, reason, err = waitForPublishButtonClickable(page)\n}","preventionTips":["Avoid reading multiple attributes from the same element handle across long intervals; re-query instead","Add WaitStable before the wait loop to reduce mid-render races","Check rod version and upgrade for CDP race fixes","Fail fast and re-open the page if the browser session is lost"],"tags":["browser-automation","rod","cdp","element-detached"],"backgroundTag":"cdp-element-attribute-failed","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"}