KnowledgeGraphManager.saveGraph() (src/memory/index.ts) writes the entire
knowledge graph directly to the memory file with:
await fs.writeFile(this.memoryFilePath, lines.join("\n"));
fs.writeFile truncates the target file and writes the new content in place.
If the process is interrupted mid-write (SIGKILL, container/host stop, crash,
OOM kill, power loss, etc.), the memory file is left truncated or partially
written — there is no atomicity guarantee.
Since this file is the sole persistence layer for the knowledge graph, a
corrupted write means silent, permanent loss of accumulated memory, with no
recovery path other than an external backup.
How to reproduce / how I found it
I verified the behavior by reading the installed source directly
(@modelcontextprotocol/server-memory, local version, same logic in
saveGraph). A realistic scenario that surfaced it: a backup script that
stops a Distrobox/Podman container hosting the server process (SIGTERM
followed by distrobox stop) — if the server is writing to the file at that
moment, the file risks being left corrupted.
Suggested fix
Write to a temporary file first, then use fs.rename(), which is atomic on
POSIX filesystems (either the old file stays intact, or the new one is
complete — never an intermediate state):
private async saveGraph(graph: KnowledgeGraph): Promise<void> {
const lines = [...]; // unchanged
const tmpPath = this.memoryFilePath + '.tmp';
await fs.writeFile(tmpPath, lines.join("\n"));
await fs.rename(tmpPath, this.memoryFilePath);
}
I applied and verified this change locally with success (no leftover .tmp
file after rename, subsequent reads/writes worked normally).
Environment
- @modelcontextprotocol/server-memory (locally installed via npm)
- Node.js on Linux (Bazzite/Distrobox)
- Bug also present in the current GitHub version (main, v0.6.3, index.ts)
KnowledgeGraphManager.saveGraph()(src/memory/index.ts) writes the entireknowledge graph directly to the memory file with:
fs.writeFiletruncates the target file and writes the new content in place.If the process is interrupted mid-write (SIGKILL, container/host stop, crash,
OOM kill, power loss, etc.), the memory file is left truncated or partially
written — there is no atomicity guarantee.
Since this file is the sole persistence layer for the knowledge graph, a
corrupted write means silent, permanent loss of accumulated memory, with no
recovery path other than an external backup.
How to reproduce / how I found it
I verified the behavior by reading the installed source directly
(
@modelcontextprotocol/server-memory, local version, same logic insaveGraph). A realistic scenario that surfaced it: a backup script thatstops a Distrobox/Podman container hosting the server process (
SIGTERMfollowed by
distrobox stop) — if the server is writing to the file at thatmoment, the file risks being left corrupted.
Suggested fix
Write to a temporary file first, then use
fs.rename(), which is atomic onPOSIX filesystems (either the old file stays intact, or the new one is
complete — never an intermediate state):
I applied and verified this change locally with success (no leftover
.tmpfile after rename, subsequent reads/writes worked normally).
Environment