{"record":{"id":"89bfb067c352a69d","repo":"xpzouying/xiaohongshu-mcp","slug":"unmarshal-notedetailmap-failed","errorCode":null,"errorMessage":"unmarshal noteDetailMap failed","messagePattern":"unmarshal noteDetailMap failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xiaohongshu/like_favorite.go","lineNumber":228,"sourceCode":"\t\t    window.__INITIAL_STATE__.note.noteDetailMap) {\n\t\t\treturn JSON.stringify(window.__INITIAL_STATE__.note.noteDetailMap);\n\t\t}\n\t\treturn \"\";\n\t}`).String()\n\tif result == \"\" {\n\t\treturn false, false, myerrors.ErrNoFeedDetail\n\t}\n\n\tvar noteDetailMap map[string]struct {\n\t\tNote struct {\n\t\t\tInteractInfo struct {\n\t\t\t\tLiked     bool `json:\"liked\"`\n\t\t\t\tCollected bool `json:\"collected\"`\n\t\t\t} `json:\"interactInfo\"`\n\t\t} `json:\"note\"`\n\t}\n\tif err := json.Unmarshal([]byte(result), &noteDetailMap); err != nil {\n\t\treturn false, false, errors.Wrap(err, \"unmarshal noteDetailMap failed\")\n\t}\n\n\tdetail, ok := noteDetailMap[feedID]\n\tif !ok {\n\t\treturn false, false, fmt.Errorf(\"feed %s not in noteDetailMap\", feedID)\n\t}\n\treturn detail.Note.InteractInfo.Liked, detail.Note.InteractInfo.Collected, nil\n}\n","sourceCodeStart":210,"sourceCodeEnd":237,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/like_favorite.go#L210-L237","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["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","Refresh the page and retry; transient timing often causes incomplete state","Re-login / refresh cookies if the state reflects a guest session","Diff the current page's __INITIAL_STATE__ against the Go struct tags and update the json tags to the new schema"],"exampleFix":"// before\nif err := json.Unmarshal([]byte(result), &noteDetailMap); err != nil {\n\treturn false, false, errors.Wrap(err, \"unmarshal noteDetailMap failed\")\n}\n// after\nif result == \"\" {\n\treturn false, false, fmt.Errorf(\"noteDetailMap empty for feed %s (note may not be loaded)\", feedID)\n}\nif err := json.Unmarshal([]byte(result), &noteDetailMap); err != nil {\n\treturn false, false, errors.Wrapf(err, \"unmarshal noteDetailMap failed, raw=%s\", result)\n}","handlingStrategy":"try-catch","validationCode":"// 解析前先校验 result 非空且是 JSON 对象\nif result == \"\" || !json.Valid([]byte(result)) {\n\treturn fmt.Errorf(\"invalid noteDetailMap payload for feed %s\", feedID)\n}","typeGuard":"func hasInteractInfo(raw string) (liked, collected bool, ok bool) {\n\tvar m map[string]struct {\n\t\tNote struct {\n\t\t\tInteractInfo struct {\n\t\t\t\tLiked     bool `json:\"liked\"`\n\t\t\t\tCollected bool `json:\"collected\"`\n\t\t\t} `json:\"interactInfo\"`\n\t\t} `json:\"note\"`\n\t}\n\tif json.Unmarshal([]byte(raw), &m) != nil {\n\t\treturn false, false, false\n\t}\n\treturn m != nil, true, true\n}","tryCatchPattern":"liked, collected, err := getInteractState(page, feedID)\nif err != nil {\n\tif strings.Contains(err.Error(), \"unmarshal noteDetailMap failed\") {\n\t\t// 页面 state 未就绪或 schema 变更：刷新后重试一次\n\t\tpage.Reload()\n\t\ttime.Sleep(2 * time.Second)\n\t\tliked, collected, err = getInteractState(page, feedID)\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"interact state check failed: %w\", err)\n\t}\n}","preventionTips":["Wait for the note page to fully load before reading __INITIAL_STATE__","Log raw eval output on failure to catch schema drift early","Refresh login cookies so state reflects an authenticated session","Pin against frontend changes by testing the selector/schema after site updates"],"tags":["go","json","unmarshal","web-automation","schema-mismatch"],"backgroundTag":"json-unmarshal-schema-mismatch","analyzedSha":"332d196854a9eac0d2b8c2c0e3d0cc43139d724c","analyzedAt":"2026-09-05T22:22:55.988Z","contentChangedAt":"2026-09-05T22:22:55.988Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}