Repository navigation
Description
Error Message
potential listener LEAK detected, popular
Stack Trace
at a.create (./src/vs/base/common/event.ts:1062:14)
at Pz._event [as onDidChange] (./src/vs/base/common/event.ts:1262:33)
at Object.u [as onWillAddFirstListener] (./src/vs/platform/actions/common/menuService.ts:437:0)
at ZCe._event [as onDidChange] (./src/vs/base/common/event.ts:1271:19)
at new or (./src/vs/platform/actions/browser/toolbar.ts:377:0)
at a._createInstance (./src/vs/platform/instantiation/common/instantiationService.ts:162:17)
at a.createInstance (./src/vs/platform/instantiation/common/instantiationService.ts:128:17)
at e6.renderTemplate (./src/vs/workbench/contrib/search/browser/searchResultsView.ts:328:0)
at mli.renderTemplate (./src/vs/base/browser/ui/tree/asyncDataTree.ts:1439:0)
at dxt.renderTemplate (./src/vs/base/browser/ui/tree/objectTree.ts:122:29)
at a.renderTemplate (./src/vs/base/browser/ui/tree/abstractTree.ts:431:0)
at (anonymous) (./src/vs/base/browser/ui/list/listWidget.ts:1273:35)
at tri.renderTemplate (./src/vs/base/browser/ui/list/listWidget.ts:1273:24)
at Byt.alloc (./src/vs/base/browser/ui/list/rowCache.ts:40:33)
at gR.insertItemInDOM (./src/vs/base/browser/ui/list/listView.ts:962:30)
at gR._splice (./src/vs/base/browser/ui/list/listView.ts:725:9)
at gR.splice (./src/vs/base/browser/ui/list/listView.ts:626:15)
at (anonymous) (./src/vs/base/browser/ui/list/splice.ts:17:34)
at Pyt.splice (./src/vs/base/browser/ui/list/splice.ts:17:19)
at (anonymous) (./src/vs/base/browser/ui/list/listWidget.ts:1621:56)
Raw Stack Trace (minified)
Error at a.create (out/vs/workbench/workbench.desktop.main.js:403:18382) at Pz._event [as onDidChange] (out/vs/workbench/workbench.desktop.main.js:405:1807) at Object.u [as onWillAddFirstListener] (out/vs/workbench/workbench.desktop.main.js:852:136431) at ZCe._event [as onDidChange] (out/vs/workbench/workbench.desktop.main.js:405:2074) at new or (out/vs/workbench/workbench.desktop.main.js:852:141276) at a._createInstance (out/vs/workbench/workbench.desktop.main.js:1899:2000) at a.createInstance (out/vs/workbench/workbench.desktop.main.js:1899:1440) at e6.renderTemplate (out/vs/workbench/workbench.desktop.main.js:3534:11096) at mli.renderTemplate (out/vs/workbench/workbench.desktop.main.js:861:43105) at dxt.renderTemplate (out/vs/workbench/workbench.desktop.main.js:861:18655) at a.renderTemplate (out/vs/workbench/workbench.desktop.main.js:860:17232) at out/vs/workbench/workbench.desktop.main.js:728:2084 at Array.map (<anonymous>) at tri.renderTemplate (out/vs/workbench/workbench.desktop.main.js:728:2075) at Byt.alloc (out/vs/workbench/workbench.desktop.main.js:685:5677) at gR.insertItemInDOM (out/vs/workbench/workbench.desktop.main.js:685:21722) at gR._splice (out/vs/workbench/workbench.desktop.main.js:685:17727) at gR.splice (out/vs/workbench/workbench.desktop.main.js:685:15999) at out/vs/workbench/workbench.desktop.main.js:683:125 at Array.forEach (<anonymous>) at Pyt.splice (out/vs/workbench/workbench.desktop.main.js:683:112) at out/vs/workbench/workbench.desktop.main.js:728:8948 at eO.bufferEvents (out/vs/workbench/workbench.desktop.main.js:405:6915) at Yai.splice (out/vs/workbench/workbench.desktop.main.js:728:8915) at Yai.splice (out/vs/workbench/workbench.desktop.main.js:860:48361) at YSe.value (out/vs/workbench/workbench.desktop.main.js:861:4465) at E._deliver (out/vs/workbench/workbench.desktop.main.js:405:3066) at E.fire (out/vs/workbench/workbench.desktop.main.js:405:3385) at YSe.value (out/vs/workbench/workbench.desktop.main.js:403:11566) at E._deliver (out/vs/workbench/workbench.desktop.main.js:405:3066) at E._deliverQueue (out/vs/workbench/workbench.desktop.main.js:405:3155) at E.fire (out/vs/workbench/workbench.desktop.main.js:405:3490) at oxt.spliceSimple (out/vs/workbench/workbench.desktop.main.js:860:4339) at oxt.splice (out/vs/workbench/workbench.desktop.main.js:860:2413) at Jz._setChildren (out/vs/workbench/workbench.desktop.main.js:861:7335) at Jz.setChildren (out/vs/workbench/workbench.desktop.main.js:861:6755) at Zai._setChildren (out/vs/workbench/workbench.desktop.main.js:861:13109) at Zai.setChildren (out/vs/workbench/workbench.desktop.main.js:861:11997) at cxt.setChildren (out/vs/workbench/workbench.desktop.main.js:861:16618) at Nxe.setChildren (out/vs/workbench/workbench.desktop.main.js:861:21074) at sy.render (out/vs/workbench/workbench.desktop.main.js:861:41132) at sy.render (out/vs/workbench/workbench.desktop.main.js:861:45662) at sy.refreshAndRenderNode (out/vs/workbench/workbench.desktop.main.js:861:37734) at async sy._updateChildren (out/vs/workbench/workbench.desktop.main.js:861:33933) at async sy.updateChildren (out/vs/workbench/workbench.desktop.main.js:861:33429) at async Hst.refreshTree (out/vs/workbench/workbench.desktop.main.js:3561:2729)
Details
| Property | Value |
|---|---|
| Bucket ID | 5c4c98d0-4846-6289-96b7-32a064e3ab97 |
| Version | 1.115.0-insider |
| Commit | 3d70aab9 |
| Last Seen | Sun Apr 05 2026 23:45:49 GMT+0000 (Coordinated Universal Time) |
| Platforms | Windows, Mac, Linux |
| Product | VSCode |
This issue was automatically created from the VS Code Errors Dashboard
Activity
vs-code-engineering commentedon Apr 7, 2026
vs-code-engineering commentedon Apr 7, 2026
🔍 Error Investigation
Summary
The error
potential listener LEAK detected, popularfires on the singletonPersistedMenuHideState._onDidChangeemitter inmenuService.ts. EveryMenuImplthat has an activeonDidChangelistener subscribes to this shared emitter. The search results view creates aMenuWorkbenchToolBar(and thus aMenuImpl) for each template across 4 renderers (TextSearchResultRenderer,FolderMatchRenderer,FileMatchRenderer,MatchRenderer), pushing the total listener count above the global leak threshold of 175. Affects 119+ users across all platforms.Culprit Commit
No single commit in the range
54b695e0...b826afb9directly modifies the affected files (event.ts,menuService.ts,toolbar.ts,searchResultsView.ts). This regression is a threshold-crossing event: the total number of activeMenuImplinstances across the entire application grew past the 175 global leak warning threshold. The 29 commits in the range include multiple Sessions/Agents UI additions that cumulatively add new menus and toolbars to the app, each subscribing to the sharedPersistedMenuHideState._onDidChangeemitter. The search results view is the "straw that broke the camel's back" — it creates many templates rapidly when rendering results, triggering the leak detection.Code Flow
sequenceDiagram participant Search as SearchResultsView<br/>renderTemplate() participant Toolbar as MenuWorkbenchToolBar<br/>constructor participant MenuImpl as MenuImpl<br/>constructor participant HiddenStates as PersistedMenuHideState<br/>._onDidChange (singleton) participant LeakMon as LeakageMonitor Search->>Toolbar: createInstance(MenuWorkbenchToolBar, MenuId.SearchActionMenu) Toolbar->>MenuImpl: menuService.createMenu(menuId) Toolbar->>MenuImpl: menu.onDidChange(callback) Note over MenuImpl: First listener → onWillAddFirstListener MenuImpl->>HiddenStates: hiddenStates.onDidChange(callback) Note over HiddenStates: ⚠️ Root cause:<br/>Singleton emitter with default<br/>threshold (175), receives one<br/>listener per active MenuImpl HiddenStates->>LeakMon: check(stack, listenerCount) Note over LeakMon: 💥 listenerCount ≥ 175<br/>Error: "potential listener<br/>LEAK detected, popular"Affected Files
src/vs/platform/actions/common/menuService.ts:59-60PersistedMenuHideState._onDidChangesingletonEmitterwith no custom leak thresholdsrc/vs/platform/actions/common/menuService.ts:437MenuImpl.startLazyListener()subscribes tohiddenStates.onDidChangesrc/vs/platform/actions/browser/toolbar.ts:377MenuWorkbenchToolBarconstructor subscribes to_menu.onDidChange, triggering lazy listenersrc/vs/workbench/contrib/search/browser/searchResultsView.ts:123,227,328,422MenuWorkbenchToolBarper template — leak triggersrc/vs/base/common/event.ts:1008-1034LeakageMonitor.check()— fires the leak error whenlistenerCount ≥ thresholdsrc/vs/workbench/browser/workbench.ts:135_globalLeakWarningThresholdto 175Repro Steps
b826afb9or later)Ctrl+Shift+F/Cmd+Shift+F)import)MenuImplinstances subscribing tohiddenStates.onDidChangeexceeds 175The error is more likely to trigger when VS Code has many menus active (editor tabs, sidebar panels, toolbars) in addition to the search results.
Fix Proposal
Option A (quick fix) — Increase the leak threshold on the singleton emitter:
Fix location:
src/vs/platform/actions/common/menuService.ts→PersistedMenuHideStateclassApproach: Change line 59 from
new Emitter(void)()tonew Emitter(void)({ leakWarningThreshold: 500 }). This emitter is a singleton that legitimately receives one listener per activeMenuImplin the entire application, so 175 is too low.Option B (structural fix) — Decouple search result templates from per-instance menus:
Fix location:
src/vs/workbench/contrib/search/browser/searchResultsView.ts→ all 4renderTemplate()methodsApproach: Instead of creating a
MenuWorkbenchToolBar(and thus aMenuImpl) per template, share a single menu instance per renderer type. The toolbar can refresh its context onrenderElementwithout needing a dedicatedMenuImplper row. This reduces the listener count onhiddenStates.onDidChangeby ~100+.Option C (hybrid) — Apply both fixes: raise the threshold to avoid false positives, and refactor search templates for efficiency.
Recommended Owner
@bryanchen-dis already assigned (error-telemetry area owner). For the fix itself,@osortega(Search area owner perworking-areas.md) is the recommended owner, as the primary fix involves the search results view template pattern. For Option A (menuService threshold),@jrieken(platform/performance owner) may want to weigh in on the appropriate threshold value.bryanchen-d commentedon Apr 7, 2026
as per analysis, this is more a false alarm:
vs-code-engineering commentedon Apr 8, 2026
Related Error Buckets
These additional error buckets are tracked by this issue (v1.114.0):
18361d63Stack path:
event.ts→menuService.ts:437→toolbar.ts:377→instantiationService→searchResultsView.ts:422— same search results view toolbar listener leak pattern as the primary bucket (different line in searchResultsView.ts but same code path through toolbar initialization).[-][Unhandled Error] potential listener LEAK detected, popular[/-][+][Unhandled Error] potential listener LEAK detected, popular — search/searchResultsView / toolbar → menuService[/+]vs-code-engineering commentedon Apr 17, 2026
vs-code-engineering commentedon Apr 21, 2026
Related Error Buckets
These error buckets continue to appear in v1.117.0-insider (previously tracked since v1.115.0-insider):
5912c915ccfc3902aa1cb938These additional error buckets are tracked by this issue (v1.117.0-insider):
634c9a3eAll from commit [
173f07e5]((insiders.vscode.dev/redacted) (Apr 20 build). The first three are the same search results view / menuService / toolbar pattern. The634c9a3ebucket is a new triggering path: the toolbar listener leak fired from chat code block rendering instead of search results.vs-code-engineering commentedon Apr 22, 2026
Related Error Buckets
These additional error buckets are tracked by this issue (v1.116.0):
a0686ebeStack path:
event.ts→menuService.ts:437→toolbar.ts→searchResultsView.ts(renderTemplate) — same search results view / menuService / toolbar listener leak pattern as the primary bucket (new bucket ID from minification drift on v1.116.0 stable). 89.6K users, 1.2M hits.vs-code-engineering commentedon Aug 11, 2026
Related Error Buckets
These error buckets continue to appear in v1.132.0 (previously tracked since v1.114.0):
This is a continuation of the previously-tracked listener leak, not a new regression.