xpzouying/xiaohongshu-mcp · error

marshal session file failed

Error message

marshal session file failed

What it means

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.

Source

Thrown at cookies/cookies.go:106

		cks = nil // 文件还不存在:先把 seed 落下来,cookies 之后再补
	}
	return c.write(cks, seed)
}

// write 以 v2 格式落盘。cookies 用 RawMessage 原样嵌入,不经过结构体往返。
func (c *localCookie) write(cks []byte, seed int) error {
	if len(cks) == 0 {
		cks = []byte("[]")
	}

	data, err := json.MarshalIndent(sessionFile{
		Version: 2,
		Seed:    seed,
		SavedAt: time.Now().Format(time.RFC3339),
		Cookies: json.RawMessage(cks),
	}, "", "  ")
	if err != nil {
		return errors.Wrap(err, "marshal session file failed")
	}

	if dir := filepath.Dir(c.path); dir != "" && dir != "." {
		if err := os.MkdirAll(dir, 0755); err != nil {
			return errors.Wrap(err, "create cookies dir failed")
		}
	}

	return os.WriteFile(c.path, data, 0644)
}

// DeleteCookies 删除 cookies 文件。
func (c *localCookie) DeleteCookies() error {
	if _, err := os.Stat(c.path); os.IsNotExist(err) {
		// 文件不存在,返回 nil(认为已经删除)
		return nil
	}
	return os.Remove(c.path)

View on GitHub (pinned to 332d196854)

Solutions

  1. Validate the cookie payload with json.Valid(data) before SaveCookies.
  2. Ensure cookies are a JSON array of objects (e.g. rod's browser.Cookies() output) — json.Marshal the []*proto.NetworkCookie slice yourself if needed.
  3. If a legacy v1 file is corrupt, DeleteCookies and re-login to rewrite it.
  4. Debug by printing the offending bytes around the json error offset (RawMessage errors include it).

Example fix

// before
err := store.SaveCookies([]byte(cookieString))
// after
if !json.Valid([]byte(cookieString)) {
    return fmt.Errorf("cookie payload is not valid JSON")
}
err := store.SaveCookies([]byte(cookieString))
Defensive patterns

Strategy: validation

Validate before calling

if !json.Valid(data) {
    return fmt.Errorf("cookie payload is not valid JSON")
}

Try / catch

err := store.SaveCookies(data)
if err != nil && strings.Contains(err.Error(), "marshal session file failed") {
    // inspect data at the error offset reported by encoding/json
    log.Printf("invalid cookie JSON: %v", err)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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