From 3722764d05874e50313a8fa4aacb81a15af0144a Mon Sep 17 00:00:00 2001 From: Tajudeen Date: Sun, 31 May 2026 14:10:50 +0100 Subject: [PATCH] fix(chat): drop per-thread caches on deleteThread to plug memory leak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to TOOLS_AUDIT_2026-05-25 §B-07. The 100-entry per-thread cap on _fileReadCache is enforced correctly, but deleteThread() never freed the per-thread bucket itself — so over a long session the cache leaks ~one bucket (up to 100 entries) per closed thread. Same pattern for _fileReadCacheLRU, _planCache, _suppressPlanOnceByThread, _pendingStreamStateUpdates, and streamState — all keyed by threadId, none cleaned up. Add the six deletes inside deleteThread() so closed threads release their state. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../contrib/cortexide/browser/chatThreadService.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/vs/workbench/contrib/cortexide/browser/chatThreadService.ts b/src/vs/workbench/contrib/cortexide/browser/chatThreadService.ts index 922cd12e9941..4e6a9ddb9d8a 100644 --- a/src/vs/workbench/contrib/cortexide/browser/chatThreadService.ts +++ b/src/vs/workbench/contrib/cortexide/browser/chatThreadService.ts @@ -5416,6 +5416,15 @@ We only need to do it for files that were edited since `from`, ie files between newCurrentId = newTabs[Math.max(0, closedIdx - 1)] ?? Object.keys(newThreads)[0] ?? '' } + // Drop per-thread caches and state so deleted threads don't leak memory + // (file-read cache hits its 100-entry per-thread cap but the bucket itself was orphaned) + this._fileReadCache.delete(threadId) + this._fileReadCacheLRU.delete(threadId) + this._planCache.delete(threadId) + this._pendingStreamStateUpdates.delete(threadId) + delete this._suppressPlanOnceByThread[threadId] + delete this.streamState[threadId] + // store the updated threads this._storeAllThreads(newThreads); this._setState({ allThreads: newThreads, openTabs: newTabs, currentThreadId: newCurrentId })