xpzouying/xiaohongshu-mcp · error

failed to unmarshal noteDetailMap: %w

Error message

failed to unmarshal noteDetailMap: %w

What it means

After extraction, extractFeedDetail unmarshals the JSON string into a map keyed by feed ID with note/comments payloads. If the JSON doesn't match that shape, it throws 'failed to unmarshal noteDetailMap: %w'.

Source

Thrown at xiaohongshu/feed_detail.go:989

		}),
	)

	if err != nil {
		logrus.Errorf("提取Feed详情失败: %v", err)
		return nil, fmt.Errorf("提取Feed详情失败: %w", err)
	}

	if result == "" {
		return nil, errors.ErrNoFeedDetail
	}

	var noteDetailMap map[string]struct {
		Note     FeedDetail  `json:"note"`
		Comments CommentList `json:"comments"`
	}

	if err := json.Unmarshal([]byte(result), &noteDetailMap); err != nil {
		return nil, fmt.Errorf("failed to unmarshal noteDetailMap: %w", err)
	}

	noteDetail, exists := noteDetailMap[feedID]
	if !exists {
		return nil, fmt.Errorf("feed %s not found in noteDetailMap", feedID)
	}

	return &FeedDetailResponse{
		Note:     noteDetail.Note,
		Comments: noteDetail.Comments,
	}, nil
}

func makeFeedDetailURL(feedID, xsecToken string) string {
	return fmt.Sprintf("https://www.xiaohongshu.com/explore/%s?xsec_token=%s&xsec_source=pc_feed", feedID, xsecToken)
}

View on GitHub (pinned to 332d196854)

Solutions

  1. Log the raw result string and compare against the expected schema
  2. Update the FeedDetail/CommentList struct json tags to match the current API shape
  3. Validate the JSON (jq or a quick unmarshal to map[string]any) to find where it diverges

Example fix

// before
var noteDetailMap map[string]struct{ Note FeedDetail `json:"note"`; Comments CommentList `json:"comments"` }
// after — inspect first
var raw map[string]json.RawMessage
if err := json.Unmarshal([]byte(result), &raw); err != nil { log.Printf("raw=%s", result); return nil, err }
Defensive patterns

Strategy: type-guard

Validate before calling

func looksLikeDetailMap(raw string) bool {
    var probe map[string]json.RawMessage
    return json.Unmarshal([]byte(raw), &probe) == nil && len(probe) > 0
}

Type guard

func asNoteDetailMap(raw string) (map[string]json.RawMessage, bool) {
    var m map[string]json.RawMessage
    if err := json.Unmarshal([]byte(raw), &m); err != nil || m == nil { return nil, false }
    return m, true
}

Try / catch

detail, err := client.GetFeedDetailWithConfig(ctx, id, cfg)
if err != nil {
    if strings.Contains(err.Error(), "unmarshal noteDetailMap") {
        log.Errorf("schema drift on %s: %v", id, err); return err
    }
    return err
}

Prevention

When it happens

Trigger: The __INITIAL_STATE__ JSON schema changed (fields renamed, note data nested differently) or the extracted string is truncated/HTML rather than the expected map.

Common situations: xiaohongshu frontend update altering the noteDetailMap structure; extraction snippet grabbing the wrong object; empty/partial page state serialized with unexpected types.

Related errors


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