xpzouying/xiaohongshu-mcp · warning
读取 checkbox 状态失败
Error message
读取 checkbox 状态失败
What it means
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.
Source
Thrown at xiaohongshu/publish.go:1106
}
}
return nil, errors.Errorf("未找到包含%q的弹窗 footer", keyword)
}
// checkFooterCheckbox 勾选 footer 内的自定义 checkbox(未勾选时才点)。
func checkFooterCheckbox(footer *rod.Element) error {
cb, err := footer.Element("div.d-checkbox")
if err != nil {
return errors.Wrap(err, "未找到须知 checkbox")
}
// 只读判断当前是否已勾选(隐藏 input.checked 或 simulator 上的 checked 态)
checked, err := cb.Eval(`() => {
const input = this.querySelector('input[type="checkbox"]');
return (input && input.checked) || this.querySelector('.checked') !== null;
}`)
if err != nil {
return errors.Wrap(err, "读取 checkbox 状态失败")
}
if checked.Value.Bool() {
return nil
}
return humanize.Click(cb)
}
func isButtonDisabled(btn *rod.Element) bool {
if disabled, _ := btn.Attribute("disabled"); disabled != nil {
return true
}
if cls, _ := btn.Attribute("class"); cls != nil && hasExactClass(*cls, "disabled") {
return true
}
return false
}
View on GitHub (pinned to 332d196854)
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
Example fix
// before
checked, err := cb.Eval(`() => { ... }`)
if err != nil {
return errors.Wrap(err, "读取 checkbox 状态失败")
}
// after
if err := cb.WaitStable(); err != nil { return err }
checked, err := cb.Eval(`() => { ... }`)
if err != nil {
cb, err = footer.Element("div.d-checkbox")
if err != nil { return err }
checked, err = cb.Eval(`() => { ... }`)
} Defensive patterns
Strategy: retry
Validate before calling
// ensure element still attached before eval
if alive, err := cb.Eval("() => document.contains(this)"); err == nil && !alive.Value.Bool() {
cb, err = footer.Element("div.d-checkbox") // re-locate
} Try / catch
err := checkFooterCheckbox(footer)
if err != nil && strings.Contains(err.Error(), "读取 checkbox 状态失败") {
time.Sleep(500 * time.Millisecond)
err = checkFooterCheckbox(footer) // single retry after re-render settles
} Prevention
- 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
When it happens
Trigger: The dialog re-rendered between footer.Element and cb.Eval (element detached); the page navigated away; the rod context expired during evaluation.
Common situations: Animations/React re-renders replacing the checkbox node right after lookup; slow pages combined with fixed sleeps; browser crash mid-flow.
Related errors
AI-assisted analysis of xpzouying/xiaohongshu-mcp@332d196854 (2026-09-05).
Data as JSON: /api/errors/8aeced312cd329ee.
Report an issue: GitHub.