Skip to content

fix(memory): atomic save + per-line parse guard against corruption (#1481)#4510

Closed
ZhangJing-gugugaga wants to merge 1 commit into
modelcontextprotocol:mainfrom
ZhangJing-gugugaga:fix/memory-corruption-resilience
Closed

fix(memory): atomic save + per-line parse guard against corruption (#1481)#4510
ZhangJing-gugugaga wants to merge 1 commit into
modelcontextprotocol:mainfrom
ZhangJing-gugugaga:fix/memory-corruption-resilience

Conversation

@ZhangJing-gugugaga

Copy link
Copy Markdown

Problem

Two defects in the memory server (issue #1481, "Memory MCP JSON Parsing Error - All Tools Failing") combine to make every tool fail on startup whenever the memory file is even slightly malformed:

  1. saveGraph overwrote the file in place with fs.writeFile. A process crash during the write left a truncated last JSONL line — producing an invalid file.
  2. loadGraph parsed each JSONL line inside the reducer with no per-line guard. A single malformed line aborted the entire loadGraph call, and since main() constructs the KnowledgeGraphManager at startup, the server died before it could serve a single request.

This turns a survivable half-write into a total, repeated startup crash.

Fix (src/memory/index.ts)

  • saveGraph now writes to a ${path}.${pid}.tmp file and fs.renames it into place — an atomic replace so a crash mid-write can never leave the real file truncated.
  • loadGraph reads first (so ENOENT still returns an empty graph), then parses each line inside its own try/catch. Malformed lines are skipped with a stderr warning instead of killing the server.

Verification

cd src/memory && npx vitest runall 30 tests pass (unchanged, 3 files / 50 tests across the whole memory suite also green). The new code does not alter the JSONL storage schema, so no migration concerns.

Added no new test cases here — a regression test for the truncated-file-resilience path requires truncating a real file on disk and is a good follow-up.

…odelcontextprotocol#1481)

Two defects in the knowledge-graph JSONL persistence caused the whole
server to fail at startup whenever the memory file was truncated or
malformed (the "JSON Parsing Error - All Tools Failing" report):

1. saveGraph wrote the file in place with fs.writeFile. A crash mid-
   write left a truncated last JSONL line. Now we write to a
   pid-suffixed .tmp file and rename into place for an atomic
   replace.

2. loadGraph relied on JSON.parse inside the reducer with no per-
   line guard, so one malformed line threw and aborted the entire
   load. Now each line is parsed in its own try/catch; bad lines are
   skipped with a stderr warning and the server keeps the valid rows.

Co-Authored-By: Claude Opus 4.6 <<EMAIL>>
@ZhangJing-gugugaga

Copy link
Copy Markdown
Author

Superseded: the memory fix was folded into PR #4509 ( branch) for a single review. Closing this duplicate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant