xpzouying/xiaohongshu-mcp · error

点击保存按钮失败

Error message

点击保存按钮失败

What it means

bindProducts wraps a clickModalSaveButton failure with this message. The save button inside the product-selection modal was found but clicking it failed (detached element, overlay, disabled state, or CDP error). Products selected in this pass may not be persisted, so the publish flow aborts.

Source

Thrown at xiaohongshu/publish.go:1159

	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)
	}

	// 点击保存按钮
	slog.Info("准备点击保存按钮")
	if err := clickModalSaveButton(modal); err != nil {
		return errors.Wrap(err, "点击保存按钮失败")
	}
	slog.Info("保存按钮点击完成,开始等待弹窗关闭")

	// 等待弹窗关闭
	if err := waitForModalClose(page); err != nil {
		slog.Warn("等待弹窗关闭超时", "error", err)
	} else {
		slog.Info("弹窗已关闭")
	}

	if len(failedProducts) > 0 {
		return errors.Errorf("部分商品未找到: %v", failedProducts)
	}

	slog.Info("商品绑定完成", "total", len(products))
	time.Sleep(1000 * time.Millisecond)
	return nil
}

View on GitHub (pinned to 332d196854)

Solutions

  1. Check the wrapped inner error for the actual click cause
  2. Ensure at least one product was selected before saving (a disabled save button can't be clicked)
  3. Wait for the button to be stable/visible before clicking
  4. Retry the whole bindProducts call with a fresh modal if the modal was destroyed

Example fix

// before
if err := clickModalSaveButton(modal); err != nil {
    return errors.Wrap(err, "点击保存按钮失败")
}
// after
if err := modal.WaitStable(); err != nil { return err }
if err := clickModalSaveButton(modal); err != nil {
    return errors.Wrap(err, "点击保存按钮失败")
}
Defensive patterns

Strategy: validation

Validate before calling

// ensure a product was selected so save is enabled
if len(failedProducts) == len(products) {
    return errors.New("无任何商品选中,保存按钮不可用")
}

Try / catch

if err := bindProducts(ctx, page, products); err != nil {
    if strings.Contains(err.Error(), "点击保存按钮失败") {
        // abort publish or re-run bindProducts with a fresh modal
    }
}

Prevention

When it happens

Trigger: The modal re-rendered after product selection, removing/replacing the save button; the button is disabled (no products selected); an overlay covers it; or the page/browser context died.

Common situations: All product searches failed (failedProducts non-empty) so the save button is disabled; slow rendering between selection and save; modal closed unexpectedly by an error toast.

Related errors


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