{"record":{"id":"5c35de3ed46e74a4","repo":"xpzouying/xiaohongshu-mcp","slug":"marshal-session-file-failed","errorCode":null,"errorMessage":"marshal session file failed","messagePattern":"marshal session file failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cookies/cookies.go","lineNumber":106,"sourceCode":"\t\tcks = nil // 文件还不存在：先把 seed 落下来，cookies 之后再补\n\t}\n\treturn c.write(cks, seed)\n}\n\n// write 以 v2 格式落盘。cookies 用 RawMessage 原样嵌入，不经过结构体往返。\nfunc (c *localCookie) write(cks []byte, seed int) error {\n\tif len(cks) == 0 {\n\t\tcks = []byte(\"[]\")\n\t}\n\n\tdata, err := json.MarshalIndent(sessionFile{\n\t\tVersion: 2,\n\t\tSeed:    seed,\n\t\tSavedAt: time.Now().Format(time.RFC3339),\n\t\tCookies: json.RawMessage(cks),\n\t}, \"\", \"  \")\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"marshal session file failed\")\n\t}\n\n\tif dir := filepath.Dir(c.path); dir != \"\" && dir != \".\" {\n\t\tif err := os.MkdirAll(dir, 0755); err != nil {\n\t\t\treturn errors.Wrap(err, \"create cookies dir failed\")\n\t\t}\n\t}\n\n\treturn os.WriteFile(c.path, data, 0644)\n}\n\n// DeleteCookies 删除 cookies 文件。\nfunc (c *localCookie) DeleteCookies() error {\n\tif _, err := os.Stat(c.path); os.IsNotExist(err) {\n\t\t// 文件不存在，返回 nil（认为已经删除）\n\t\treturn nil\n\t}\n\treturn os.Remove(c.path)","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/cookies/cookies.go#L88-L124","documentation":"The write helper fails when json.MarshalIndent of the v2 sessionFile struct errors (cookies/cookies.go:106). Cookies are embedded as json.RawMessage, so this fails when the stored cookie bytes are not valid JSON — RawMessage marshaling validates the payload. Seed, SavedAt, and Version are plain scalars and cannot fail.","triggerScenarios":"Calling SaveCookies(data) or SaveSeed(seed) where `data` (or the cookies previously loaded by SaveSeed via LoadCookies) is not well-formed JSON — e.g. passing raw Set-Cookie header text, truncated bytes, or a non-object/non-array payload.","commonSituations":"Caller scraped cookies as a string and passed []byte(str) without JSON-encoding; a corrupted older cookie file whose contents are returned verbatim by LoadCookies' v1 fallback and then re-embedded as RawMessage.","solutions":["Validate the cookie payload with json.Valid(data) before SaveCookies.","Ensure cookies are a JSON array of objects (e.g. rod's browser.Cookies() output) — json.Marshal the []*proto.NetworkCookie slice yourself if needed.","If a legacy v1 file is corrupt, DeleteCookies and re-login to rewrite it.","Debug by printing the offending bytes around the json error offset (RawMessage errors include it)."],"exampleFix":"// before\nerr := store.SaveCookies([]byte(cookieString))\n// after\nif !json.Valid([]byte(cookieString)) {\n    return fmt.Errorf(\"cookie payload is not valid JSON\")\n}\nerr := store.SaveCookies([]byte(cookieString))","handlingStrategy":"validation","validationCode":"if !json.Valid(data) {\n    return fmt.Errorf(\"cookie payload is not valid JSON\")\n}","typeGuard":null,"tryCatchPattern":"err := store.SaveCookies(data)\nif err != nil && strings.Contains(err.Error(), \"marshal session file failed\") {\n    // inspect data at the error offset reported by encoding/json\n    log.Printf(\"invalid cookie JSON: %v\", err)\n}","preventionTips":["Always json.Valid() cookie bytes before SaveCookies.","Pass serialized cookie structs (e.g. json.Marshal of rod cookies), never raw header strings.","Delete corrupted legacy v1 cookie files instead of round-tripping them."],"tags":["json","serialization","cookies","session"],"backgroundTag":"json-marshal-failed","analyzedSha":"332d196854a9eac0d2b8c2c0e3d0cc43139d724c","analyzedAt":"2026-09-05T22:22:55.988Z","contentChangedAt":"2026-09-05T22:22:55.988Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}