xpzouying/xiaohongshu-mcp · warning

login status element not found

Error message

login status element not found

What it means

CheckLoginStatus concludes the user is NOT logged in when the `.main-container .user .link-wrapper .channel` element is absent from the explore page, and returns this error. Note the bug: errors.Wrap(err, ...) is called with err == nil here, so the resulting error is effectively errors.New("login status element not found"). It conflates 'definitely logged out' with 'page rendered differently than expected'.

Solutions

  1. Manually open the explore page in the same browser profile and inspect whether the selector still exists; update the CSS selector if the DOM changed
  2. Replace the fixed time.Sleep with rod's Wait/WaitRequestIdle or retry Has a few times before concluding logged-out
  3. Re-run the Login flow to refresh cookies, then call CheckLoginStatus again
  4. Return a typed 'not logged in' sentinel instead of relying on the wrapped (nil) error, and use errors.Is in callers

Example fix

// before
if !exists {
	return false, errors.Wrap(err, "login status element not found")
}
// after
if !exists {
	// 再等待重试一次,排除慢渲染导致的误判
	pp.WaitStable(500 * time.Millisecond)
	if exists2, _, _ := pp.Has(`.main-container .user .link-wrapper .channel`); !exists2 {
		return false, errors.New("login status element not found (likely logged out)")
	}
}
Defensive patterns

Strategy: fallback

Validate before calling

// 调用前先确认有会话 cookie
cookies, _ := page.Cookies("https://www.xiaohongshu.com")
hasSession := false
for _, c := range cookies {
	if c.Name == "web_session" && c.Value != "" {
		hasSession = true
	}
}
if !hasSession {
	return errors.New("no session cookie, login required")
}

Type guard

func isNotLoggedInErr(err error) bool {
	return err != nil && strings.Contains(err.Error(), "login status element not found")
}

Try / catch

loggedIn, err := loginAction.CheckLoginStatus(ctx)
if err != nil {
	if isNotLoggedInErr(err) {
		// 回退:走完整登录流程后重查
		if err := loginAction.Login(ctx); err != nil {
			return err
		}
		loggedIn, err = loginAction.CheckLoginStatus(ctx)
	}
	if err != nil {
		return err
	}
}
_ = loggedIn

Prevention

When it happens

Trigger: Calling CheckLoginStatus when: the session cookie expired so the page shows the logged-out layout; Xiaohongshu changed/expired the DOM class names (A/B tests, redesign); the 1-second sleep was not enough and the user menu hadn't rendered yet; a lightweight/anti-bot page variant rendered without the .main-container structure.

Common situations: Long-lived sessions expiring overnight; site frontend update renaming .link-wrapper/.channel classes; headless fingerprint flagged and served a degraded page; slow render where the element appears after the query but the library doesn't wait for it.

Related errors


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

Appendix: source

Thrown at xiaohongshu/login.go:33

func NewLogin(page *rod.Page) *LoginAction {
	return &LoginAction{page: page}
}

func (a *LoginAction) CheckLoginStatus(ctx context.Context) (bool, error) {
	// 加超时保护:只是查登录态的快速检查,不应无限挂(登录扫码的等待在 Login/WaitForLogin 里)
	pp := a.page.Context(ctx).Timeout(30 * time.Second)
	pp.MustNavigate("https://www.xiaohongshu.com/explore").MustWaitLoad()

	time.Sleep(1 * time.Second)

	exists, _, err := pp.Has(`.main-container .user .link-wrapper .channel`)
	if err != nil {
		return false, errors.Wrap(err, "check login status failed")
	}

	if !exists {
		return false, errors.Wrap(err, "login status element not found")
	}

	return true, nil
}

// CurrentUser 当前登录用户的基础信息。
type CurrentUser struct {
	Nickname string `json:"nickname"`
	UserID   string `json:"userId"`
}

// CurrentUser 从当前页面的 __INITIAL_STATE__ 读取登录用户信息。
// 需在 CheckLoginStatus 之后调用:复用已加载的 explore 页,不做额外导航。
func (a *LoginAction) CurrentUser(ctx context.Context) (*CurrentUser, error) {
	pp := a.page.Context(ctx).Timeout(10 * time.Second)

	res, err := pp.Eval(`() => {
		const u = window.__INITIAL_STATE__ && window.__INITIAL_STATE__.user;

View on GitHub (pinned to 332d196854)