xpzouying/xiaohongshu-mcp · error

读取旧版发布按钮 disabled 属性失败

Error message

读取旧版发布按钮 disabled 属性失败

What it means

This error is wrapped in findPublishButton when the CDP call to read the `disabled` attribute of a visible legacy (old-version) Xiaohongshu publish button fails. It means the rod Element.Attribute call itself errored (browser/tab closed, element detached, CDP communication failure), not that the button is disabled. The library throws it because it cannot determine clickability without the attribute value.

Solutions

  1. Retry waitForPublishButtonClickable with a small delay — the element likely got detached by a page re-render; the polling loop will re-query fresh elements
  2. Check that the browser process and target tab are still alive (rod.Browser / page.MustTarget) before retrying
  3. Increase page load waits (page.WaitStable / WaitDOMStable) before triggering publish so elements stop mutating mid-check
  4. Upgrade rod to the latest version to rule out known CDP race bugs

Example fix

// before
btn, reason, err := waitForPublishButtonClickable(page)
// after
err = page.WaitDOMStable(time.Second, 0.1)
if err != nil { return err }
btn, reason, err := waitForPublishButtonClickable(page)
Defensive patterns

Strategy: retry

Validate before calling

if page == nil { return errors.New("page 未初始化") }
if err := page.WaitStable(300 * time.Millisecond); err != nil { return err }

Type guard

func pageAlive(page *rod.Page) bool {
    if page == nil { return false }
    _, err := page.Elements("body")
    return err == nil
}

Try / catch

btn, reason, err := waitForPublishButtonClickable(page)
if err != nil {
    if strings.Contains(err.Error(), "读取旧版发布按钮 disabled 属性失败") {
        time.Sleep(500 * time.Millisecond)
        btn, reason, err = waitForPublishButtonClickable(page)
    }
    if err != nil { return err }
}

Prevention

When it happens

Trigger: Calling waitForPublishButtonClickable while the page is being navigated or reloading so the matched `.publish-page-publish-btn button.bg-red` element is detached between query and attribute read; the browser context/tab was closed mid-poll; CDP connection dropped.

Common situations: Slow page loads where the old publish button is replaced by React re-renders; user closes the Chrome window during automation; network hiccup breaking the DevTools websocket; running against a stale rod.Page after navigation.

Related errors


AI-assisted analysis of xpzouying/xiaohongshu-mcp@332d196854 (2026-09-05). Data as JSON: /api/errors/9b0284b83a06259e. Report an issue: GitHub.

Appendix: source

Thrown at xiaohongshu/publish.go:522

		if submitDisabled != nil && *submitDisabled == "true" {
			return &publishButton{elem: widget, isWidget: true}, "新版发布按钮不可点击", nil
		}

		return &publishButton{elem: widget, isWidget: true}, "", nil
	}

	oldButtons, err := page.Elements(".publish-page-publish-btn button.bg-red")
	if err != nil {
		return nil, "", errors.Wrap(err, "查找旧版发布按钮失败")
	}

	for _, oldButton := range oldButtons {
		if !isElementVisible(oldButton) {
			continue
		}

		if disabled, err := oldButton.Attribute("disabled"); err != nil {
			return nil, "", errors.Wrap(err, "读取旧版发布按钮 disabled 属性失败")
		} else if disabled != nil {
			return &publishButton{elem: oldButton}, "旧版发布按钮 disabled", nil
		}

		if ariaDisabled, err := oldButton.Attribute("aria-disabled"); err != nil {
			return nil, "", errors.Wrap(err, "读取旧版发布按钮 aria-disabled 属性失败")
		} else if ariaDisabled != nil && *ariaDisabled == "true" {
			return &publishButton{elem: oldButton}, "旧版发布按钮 aria-disabled=true", nil
		}

		if cls, err := oldButton.Attribute("class"); err != nil {
			return nil, "", errors.Wrap(err, "读取旧版发布按钮 class 属性失败")
		} else if cls != nil && hasExactClass(*cls, "disabled") {
			return &publishButton{elem: oldButton}, "旧版发布按钮包含 disabled class", nil
		}

		return &publishButton{elem: oldButton}, "", nil
	}

View on GitHub (pinned to 332d196854)