{"record":{"id":"8aeced312cd329ee","repo":"xpzouying/xiaohongshu-mcp","slug":"checkbox-8aeced","errorCode":null,"errorMessage":"读取 checkbox 状态失败","messagePattern":"读取 checkbox 状态失败","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"xiaohongshu/publish.go","lineNumber":1106,"sourceCode":"\t\t}\n\t}\n\treturn nil, errors.Errorf(\"未找到包含%q的弹窗 footer\", keyword)\n}\n\n// checkFooterCheckbox 勾选 footer 内的自定义 checkbox（未勾选时才点）。\nfunc checkFooterCheckbox(footer *rod.Element) error {\n\tcb, err := footer.Element(\"div.d-checkbox\")\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"未找到须知 checkbox\")\n\t}\n\n\t// 只读判断当前是否已勾选（隐藏 input.checked 或 simulator 上的 checked 态）\n\tchecked, err := cb.Eval(`() => {\n\t\tconst input = this.querySelector('input[type=\"checkbox\"]');\n\t\treturn (input && input.checked) || this.querySelector('.checked') !== null;\n\t}`)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"读取 checkbox 状态失败\")\n\t}\n\tif checked.Value.Bool() {\n\t\treturn nil\n\t}\n\n\treturn humanize.Click(cb)\n}\n\nfunc isButtonDisabled(btn *rod.Element) bool {\n\tif disabled, _ := btn.Attribute(\"disabled\"); disabled != nil {\n\t\treturn true\n\t}\n\tif cls, _ := btn.Attribute(\"class\"); cls != nil && hasExactClass(*cls, \"disabled\") {\n\t\treturn true\n\t}\n\treturn false\n}\n","sourceCodeStart":1088,"sourceCodeEnd":1124,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/publish.go#L1088-L1124","documentation":"checkFooterCheckbox wraps a failure from cb.Eval with this message. The read-only JS snippet checking input.checked or a .checked class could not run — typically because the element's execution context vanished or the object was garbage-collected by rod between lookup and eval. Callers only warn upstream, but the checkbox state stays unknown.","triggerScenarios":"The dialog re-rendered between footer.Element and cb.Eval (element detached); the page navigated away; the rod context expired during evaluation.","commonSituations":"Animations/React re-renders replacing the checkbox node right after lookup; slow pages combined with fixed sleeps; browser crash mid-flow.","solutions":["Re-locate the checkbox and retry the Eval once on failure","Wait for the element to be stable (WaitStable) before evaluating","Check the wrapped inner error for 'object reference chain too long'/'detached' hints and treat as re-render","Replace fixed sleeps with waits so eval happens after rendering settles"],"exampleFix":"// before\nchecked, err := cb.Eval(`() => { ... }`)\nif err != nil {\n    return errors.Wrap(err, \"读取 checkbox 状态失败\")\n}\n// after\nif err := cb.WaitStable(); err != nil { return err }\nchecked, err := cb.Eval(`() => { ... }`)\nif err != nil {\n    cb, err = footer.Element(\"div.d-checkbox\")\n    if err != nil { return err }\n    checked, err = cb.Eval(`() => { ... }`)\n}","handlingStrategy":"retry","validationCode":"// ensure element still attached before eval\nif alive, err := cb.Eval(\"() => document.contains(this)\"); err == nil && !alive.Value.Bool() {\n    cb, err = footer.Element(\"div.d-checkbox\") // re-locate\n}","typeGuard":null,"tryCatchPattern":"err := checkFooterCheckbox(footer)\nif err != nil && strings.Contains(err.Error(), \"读取 checkbox 状态失败\") {\n    time.Sleep(500 * time.Millisecond)\n    err = checkFooterCheckbox(footer) // single retry after re-render settles\n}","preventionTips":["Re-locate the element before retrying Eval","Use WaitStable before JS evaluation","Avoid navigating the page during the originality dialog","Log inner rod errors to distinguish detach from context cancel"],"tags":["go-rod","javascript-eval","element-detached"],"backgroundTag":"rod-eval-detached-element","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"}