xpzouying/xiaohongshu-mcp · error
unmarshal current user failed
Error message
unmarshal current user failed
What it means
CurrentUser builds a JSON string inside the page (JSON.stringify of nickname/userId) and decodes it into the CurrentUser struct with json.Unmarshal. 'unmarshal current user failed' means the string returned by the page is not valid JSON or its shape doesn't satisfy the struct's expectations, so decoding into CurrentUser{Nickname,UserID} failed.
Source
Thrown at xiaohongshu/login.go:67
res, err := pp.Eval(`() => {
const u = window.__INITIAL_STATE__ && window.__INITIAL_STATE__.user;
const info = u && u.userInfo && u.userInfo.value !== undefined ? u.userInfo.value : (u && u.userInfo);
if (!info || info.guest) return "";
return JSON.stringify({nickname: info.nickname, userId: info.userId || info.user_id});
}`)
if err != nil {
return nil, errors.Wrap(err, "read current user state failed")
}
raw := res.Value.String()
if raw == "" {
return nil, errors.New("current user not found in page state")
}
var user CurrentUser
if err := json.Unmarshal([]byte(raw), &user); err != nil {
return nil, errors.Wrap(err, "unmarshal current user failed")
}
return &user, nil
}
func (a *LoginAction) Login(ctx context.Context) 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 nil
}
pp.MustElement(".main-container .user .link-wrapper .channel")View on GitHub (pinned to 332d196854)
Solutions
- Log the raw value of res.Value.String() to see what the page actually returned
- Compare it against the CurrentUser struct {nickname string, userId string} and update the eval JS or struct tags to match the new site shape
- Make the eval stricter: build the object explicitly with String(info.nickname) and String(info.userId||info.user_id) so Unmarshal always receives strings
- Pin/update the library version after checking whether xiaohongshu changed __INITIAL_STATE__ (this is a scraping-fragility error, not a caller bug)
Example fix
// before
return JSON.stringify({nickname: info.nickname, userId: info.userId || info.user_id});
// after
return JSON.stringify({nickname: String(info.nickname ?? ""), userId: String(info.userId ?? info.user_id ?? "")}); Defensive patterns
Strategy: type-guard
Validate before calling
raw := ""
// decode defensively after reading page state
var probe map[string]any
if err := json.Unmarshal([]byte(raw), &probe); err != nil { return nil, fmt.Errorf("page returned non-JSON: %q", raw) } Type guard
func looksLikeUserJSON(s string) bool {
var v struct {
Nickname string `json:"nickname"`
UserID string `json:"userId"`
}
return json.Unmarshal([]byte(s), &v) == nil
} Try / catch
user, err := login.CurrentUser(ctx)
if err != nil {
if strings.Contains(err.Error(), "unmarshal current user failed") {
// site state shape changed; log raw payload and degrade gracefully
return nil, ErrUserParseUnavailable
}
return err
} Prevention
- Log the raw JSON the page returns whenever unmarshal fails, to detect site redesigns early
- Pin a known-good library version and check its issues before upgrading
- Pin expectations in your own integration test: CurrentUser must return non-empty Nickname
- Handle userId arriving as a number in the JSON by accepting json.Number in custom types
When it happens
Trigger: The page's __INITIAL_STATE__ yields fields that are not strings (e.g. userId as a number is fine, but nested objects/arrays serialized differently will not match); a xiaohongshu front-end change makes the eval return a different structure (e.g. the whole info object instead of {nickname,userId}); locale/encoding issues corrupt the JSON string.
Common situations: Site redesign moving user info out of __INITIAL_STATE__.user.userInfo; the eval's fallback branch (u.userInfo without .value) returning an object with extra/non-JSON-compatible content; data races where the state updates mid-stringify.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- 解析通知列表失败: %w
- failed to unmarshal userPageData: %w
- failed to unmarshal notes: %w
- unmarshal noteDetailMap failed
- failed to unmarshal noteDetailMap: %w
AI-assisted analysis of xpzouying/xiaohongshu-mcp@332d196854 (2026-09-05).
Data as JSON: /api/errors/47d79e277e77becb.
Report an issue: GitHub.