From c0792e53761a2b4737dd3d9e5d7459ddba553e71 Mon Sep 17 00:00:00 2001 From: zeroaltitude Date: Tue, 10 Mar 2026 00:19:54 -0700 Subject: [PATCH] fix: restore pre-existing content on ENOENT during late-block retraction When a slug collision exists (preExistingContent !== null) and the file is externally deleted before the post-hook drain, the ENOENT handler now restores the prior session's content instead of returning early. The inline overwrite already destroyed the original file, so early return would permanently lose the prior session's memory. --- src/hooks/bundled/session-memory/handler.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/hooks/bundled/session-memory/handler.ts b/src/hooks/bundled/session-memory/handler.ts index 60043293e84..1a8fb597e05 100644 --- a/src/hooks/bundled/session-memory/handler.ts +++ b/src/hooks/bundled/session-memory/handler.ts @@ -476,8 +476,23 @@ const saveSessionToMemory: HookHandler = async (event) => { "code" in err && (err as NodeJS.ErrnoException).code === "ENOENT" ) { - // File was externally deleted — nothing to retract. - log.debug("Session save retraction skipped — file already removed"); + if (preExistingContent !== null) { + // Our inline write overwrote a pre-existing entry (slug collision), + // and the file was subsequently deleted externally. Restore the + // prior session's content — it was lost to our inline overwrite. + await writeFileWithinRoot({ + rootDir: memoryDir, + relativePath: filename, + data: preExistingContent, + encoding: "utf-8", + }); + log.debug( + "Session save retracted by post-hook — pre-existing file restored after external deletion", + ); + } else { + // No prior content existed — file was externally deleted, nothing to restore. + log.debug("Session save retraction skipped — file already removed"); + } return; } throw err;