xpzouying/xiaohongshu-mcp · error
qrcode src is empty
Error message
qrcode src is empty
What it means
FetchQrcodeImage reads the src attribute of the '.login-container .qrcode-img' element; if the attribute is nil or an empty string it returns 'qrcode src is empty' along with false (not expired). It means the QR code image element exists but carries no image URL, so the login QR cannot be fetched.
Solutions
- Wait for the QR image to finish loading (WaitVisible/WaitRequestIdle) before reading the src attribute
- Retry FetchQrcodeImage after a short delay — the src is often populated asynchronously
- Capture a screenshot when it fails to see whether a captcha/verify page replaced the login UI
- Update the '.login-container .qrcode-img' selector if the site markup changed
Example fix
// before
src, expired, err := login.FetchQrcodeImage(ctx)
if err != nil { return err }
// after
var src string
var expired bool
var err error
for i := 0; i < 3; i++ {
src, expired, err = login.FetchQrcodeImage(ctx)
if err == nil || !strings.Contains(err.Error(), "qrcode src is empty") { break }
time.Sleep(2 * time.Second)
}
if err != nil { return err } Defensive patterns
Strategy: retry
Validate before calling
_, err := page.Element(".login-container .qrcode-img")
// only proceed if the element exists; wait if err != nil Try / catch
var src string; var err error
for i := 0; i < 3; i++ {
src, _, err = login.FetchQrcodeImage(ctx)
if err == nil || !strings.Contains(err.Error(), "qrcode src is empty") { break }
time.Sleep(2 * time.Second)
}
if err != nil { return err } Prevention
- Wait for the login widget to finish initializing before fetching the QR
- Retry with delay: src is often set asynchronously
- Screenshot on failure to detect captcha pages replacing the QR UI
When it happens
Trigger: Calling LoginAction.FetchQrcodeImage (xiaohongshu/login.go:107) when the qrcode img has no src — the QR hasn't been generated yet after page load, the login container is a fallback variant without the expected element, or a verify/interstitial page replaced the login page.
Common situations: Fetching the QR immediately after navigation before the login widget finishes initializing; XHS serving a slider-captcha instead of the QR login; DOM changes renaming .qrcode-img so the selector matches a stale/empty placeholder img.
Related errors
- current user not found in page state
- 通知条目渲染数( )少于目标位置( ),页面可能未加载完
- 查找正文输入框失败
- 声明原创按钮仍处于禁用状态
- 未找到添加商品按钮,账号可能未开通商品功能
AI-assisted analysis of xpzouying/xiaohongshu-mcp@332d196854 (2026-09-05).
Data as JSON: /api/errors/0f2b4a0e55a5e007.
Report an issue: GitHub.
Appendix: source
Thrown at xiaohongshu/login.go:107
func (a *LoginAction) FetchQrcodeImage(ctx context.Context) (string, bool, error) {
pp := a.page.Context(ctx)
// 导航到小红书首页,这会触发二维码弹窗
pp.MustNavigate("https://www.xiaohongshu.com/explore").MustWaitLoad()
time.Sleep(2 * time.Second)
if exists, _, _ := pp.Has(".main-container .user .link-wrapper .channel"); exists {
return "", true, nil
}
src, err := pp.MustElement(".login-container .qrcode-img").Attribute("src")
if err != nil {
return "", false, errors.Wrap(err, "get qrcode src failed")
}
if src == nil || len(*src) == 0 {
return "", false, errors.New("qrcode src is empty")
}
return *src, false, nil
}
func (a *LoginAction) WaitForLogin(ctx context.Context) bool {
pp := a.page.Context(ctx)
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return false
case <-ticker.C:
el, err := pp.Element(".main-container .user .link-wrapper .channel")
if err == nil && el != nil {
return trueView on GitHub (pinned to 332d196854)