xpzouying/xiaohongshu-mcp · error

点击添加商品按钮失败

Error message

点击添加商品按钮失败

What it means

bindProducts wraps a clickAddProductButton failure with this message. That helper searches all span.d-text elements for the exact text '添加商品' and walks up to a clickable parent; failing means the button wasn't found or its click failed. Product binding cannot proceed and the whole publish submission errors out.

Solutions

  1. Increase the wait before searching or poll for the '添加商品' span with a deadline
  2. Verify the account has product-binding permission (button renders only then)
  3. Log all span.d-text texts when not found to detect text changes
  4. Update the selector/text constant if the frontend changed

Example fix

// before
spans, err := page.Elements("span.d-text")
// after
var span *rod.Element
err := rod.Try(func() error {
    el, e := page.Timeout(10*time.Second).ElementR("span.d-text", "添加商品")
    span = el; return e
})
Defensive patterns

Strategy: validation

Validate before calling

// confirm the add-product entry exists before binding
if _, err := page.ElementR("span.d-text", "添加商品"); err != nil {
    return fmt.Errorf("添加商品入口不可用(检查账号权限/页面加载): %w", err)
}

Try / catch

if err := bindProducts(ctx, page, products); err != nil {
    if strings.Contains(err.Error(), "点击添加商品按钮失败") {
        // skip product binding or abort publish with a clear reason
    }
}

Prevention

When it happens

Trigger: The publish page has no '添加商品' span (page not fully loaded, no product module for the account, or text/selector changed), or page.Elements("span.d-text")/humanize.Click returned an error.

Common situations: Page still loading when bindProducts runs (fixed sleeps only); account without e-commerce permission so the button isn't rendered; frontend redesign renaming the text or d-text class.

Related errors


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

Appendix: source

Thrown at xiaohongshu/publish.go:1135

		return true
	}
	if cls, _ := btn.Attribute("class"); cls != nil && hasExactClass(*cls, "disabled") {
		return true
	}
	return false
}

// bindProducts 绑定商品到发布内容
func bindProducts(ctx context.Context, page *rod.Page, products []string) error {
	if len(products) == 0 {
		return nil
	}

	slog.Info("开始绑定商品", "products", products)

	// 点击"添加商品"按钮
	if err := clickAddProductButton(page); err != nil {
		return errors.Wrap(err, "点击添加商品按钮失败")
	}
	time.Sleep(1 * time.Second)

	// 等待商品选择弹窗出现
	modal, err := waitForProductModal(page)
	if err != nil {
		return errors.Wrap(err, "等待商品弹窗失败")
	}
	slog.Info("商品选择弹窗已打开")

	// 遍历搜索并选择商品
	var failedProducts []string
	for _, keyword := range products {
		if err := searchAndSelectProduct(ctx, page, modal, keyword); err != nil {
			slog.Warn("搜索选择商品失败", "keyword", keyword, "error", err)
			failedProducts = append(failedProducts, keyword)
		}
		time.Sleep(500 * time.Millisecond)

View on GitHub (pinned to 332d196854)