xpzouying/xiaohongshu-mcp · error

failed to unmarshal userPageData: %w

Error message

failed to unmarshal userPageData: %w

What it means

extractUserProfileData 已拿到 userPageData JSON,但 json.Unmarshal 到匿名结构体(interactions/basicInfo)失败:页面数据结构与定义不符(前端改版)或数据截断。

Source

Thrown at xiaohongshu/user_profile.go:105

		if (!u || !u.notes) return "";
		const unwrap = (o) => (o && o.value !== undefined) ? o.value : (o && o._value);
		const notes = unwrap(u.notes);
		if (!notes) return "";
		const active = unwrap(u.activeTab) || {};
		return JSON.stringify({notes: notes, index: active.index || 0, query: active.query || ""});
	}`).String()

	if notesResult == "" {
		return nil, fmt.Errorf("user.notes.value not found in __INITIAL_STATE__")
	}

	// 解析用户信息
	var userPageData struct {
		Interactions []UserInteractions `json:"interactions"`
		BasicInfo    UserBasicInfo      `json:"basicInfo"`
	}
	if err := json.Unmarshal([]byte(userDataResult), &userPageData); err != nil {
		return nil, fmt.Errorf("failed to unmarshal userPageData: %w", err)
	}

	var notesData struct {
		Notes [][]Feed `json:"notes"`
		Index int      `json:"index"`
		Query string   `json:"query"`
	}
	if err := json.Unmarshal([]byte(notesResult), &notesData); err != nil {
		return nil, fmt.Errorf("failed to unmarshal notes: %w", err)
	}

	// tab 不符时报错,避免把别的 tab 的内容当成结果返回
	want := tab
	if want == "" {
		want = TabNotes
	}
	if notesData.Query != "" && ProfileTab(notesData.Query) != want {
		return nil, fmt.Errorf("当前 tab 为 %q,与请求的 %q 不符", notesData.Query, want)

View on GitHub (pinned to 332d196854)

Solutions

  1. 查看包装的底层 json 错误定位具体字段,升级库版本适配新 schema
  2. 检查返回的 userDataResult 是否为 null/空对象(数据缺失被序列化成了 JSON)
  3. 必要时在本地用自定义解析兼容新字段
  4. 向库维护者报告新版页面结构差异

Example fix

// before
res, err := client.UserProfile(ctx, userID, "note") // Unmarshal 失败
// after
if err != nil && strings.Contains(err.Error(), "unmarshal userPageData") {
    log.Printf("页面 schema 可能已变更: %v", err) // 查看底层 %w 错误
    return upgradeLibraryAndRetry()
}
Defensive patterns

Strategy: type-guard

Validate before calling

// 调用前检查返回的 JSON 非空且非 null
if userDataResult == "" || userDataResult == "null" {
    return errors.New("userPageData 为空,页面可能未加载完成")
}

Type guard

func looksLikeUserPageData(raw string) bool {
    var probe struct {
        BasicInfo json.RawMessage `json:"basicInfo"`
    }
    return json.Unmarshal([]byte(raw), &probe) == nil && len(probe.BasicInfo) > 0
}

Try / catch

res, err := client.UserProfile(ctx, userID, tab)
var jsonErr error
if err != nil && errors.As(err, &jsonErr) && strings.Contains(err.Error(), "unmarshal userPageData") {
    // 底层 %w 错误可定位具体字段,提示 schema 变更
    log.Printf("schema 变更: %v", jsonErr)
}

Prevention

When it happens

Trigger: 调用 UserProfile / GetMyProfileViaSidebar 时,__INITIAL_STATE__ 中 userPageData.value 的 JSON 字段类型/结构与 UserInteractions、UserBasicInfo 定义不符,导致 Unmarshal 报错(如类型变化、字符串变数字、null 处理)。

Common situations: 小红书改版调整了 basicInfo/interactions 字段类型;新增/删除字段导致结构不兼容;Eval 返回的是 "null" 字符串而非合法 JSON 对象。

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


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