xpzouying/xiaohongshu-mcp · error

unmarshal noteDetailMap failed

Error message

unmarshal noteDetailMap failed

What it means

getInteractState unmarshals the JSON string returned by the browser-evaluated noteDetailMap lookup into a typed map keyed by feed ID. This error means the JSON did not match the expected structure (noteDetailMap -> feedID -> note.interactInfo.{liked,collected}) or the string was not valid JSON at all (e.g. empty string returned when the state was absent).

Source

Thrown at xiaohongshu/like_favorite.go:228

		    window.__INITIAL_STATE__.note.noteDetailMap) {
			return JSON.stringify(window.__INITIAL_STATE__.note.noteDetailMap);
		}
		return "";
	}`).String()
	if result == "" {
		return false, false, myerrors.ErrNoFeedDetail
	}

	var noteDetailMap map[string]struct {
		Note struct {
			InteractInfo struct {
				Liked     bool `json:"liked"`
				Collected bool `json:"collected"`
			} `json:"interactInfo"`
		} `json:"note"`
	}
	if err := json.Unmarshal([]byte(result), &noteDetailMap); err != nil {
		return false, false, errors.Wrap(err, "unmarshal noteDetailMap failed")
	}

	detail, ok := noteDetailMap[feedID]
	if !ok {
		return false, false, fmt.Errorf("feed %s not in noteDetailMap", feedID)
	}
	return detail.Note.InteractInfo.Liked, detail.Note.InteractInfo.Collected, nil
}

View on GitHub (pinned to 332d196854)

Solutions

  1. Log the raw `result` string when the error occurs; if it is empty, the note was not loaded — wait/retry after the note page settles
  2. Refresh the page and retry; transient timing often causes incomplete state
  3. Re-login / refresh cookies if the state reflects a guest session
  4. Diff the current page's __INITIAL_STATE__ against the Go struct tags and update the json tags to the new schema

Example fix

// before
if err := json.Unmarshal([]byte(result), &noteDetailMap); err != nil {
	return false, false, errors.Wrap(err, "unmarshal noteDetailMap failed")
}
// after
if result == "" {
	return false, false, fmt.Errorf("noteDetailMap empty for feed %s (note may not be loaded)", feedID)
}
if err := json.Unmarshal([]byte(result), &noteDetailMap); err != nil {
	return false, false, errors.Wrapf(err, "unmarshal noteDetailMap failed, raw=%s", result)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// 解析前先校验 result 非空且是 JSON 对象
if result == "" || !json.Valid([]byte(result)) {
	return fmt.Errorf("invalid noteDetailMap payload for feed %s", feedID)
}

Type guard

func hasInteractInfo(raw string) (liked, collected bool, ok bool) {
	var m map[string]struct {
		Note struct {
			InteractInfo struct {
				Liked     bool `json:"liked"`
				Collected bool `json:"collected"`
			} `json:"interactInfo"`
		} `json:"note"`
	}
	if json.Unmarshal([]byte(raw), &m) != nil {
		return false, false, false
	}
	return m != nil, true, true
}

Try / catch

liked, collected, err := getInteractState(page, feedID)
if err != nil {
	if strings.Contains(err.Error(), "unmarshal noteDetailMap failed") {
		// 页面 state 未就绪或 schema 变更:刷新后重试一次
		page.Reload()
		time.Sleep(2 * time.Second)
		liked, collected, err = getInteractState(page, feedID)
	}
	if err != nil {
		return fmt.Errorf("interact state check failed: %w", err)
	}
}

Prevention

When it happens

Trigger: Calling perform/waitInteractState on a note whose page state differs from the expected schema: note is deleted/private, the user is not logged in so __INITIAL_STATE__ lacks noteDetailMap, Xiaohongshu changed its frontend JSON shape, or the JS eval returned "" because the note was not found in state.

Common situations: Interacting (like/favorite) too quickly before the note detail finished loading into state; target note removed or restricted; site frontend update renames noteDetailMap/interactInfo fields; stale session cookie causing guest state.

Related errors


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