Change:
It looks like everything is getting disposed properly and I haven't been able to find a way to repro. It looks like this has only been seen on builds that are 12 days old. Let's see if we see it again.
I can repro if I have a tree with ~145 elements visible, as each one has a listener for whether the inline menu items change base on context key value changes. This listener is also apparently listening for whether a menu item's "hidden state" also changes, which is where the problem occurs. It seems that every menu in the workbench listens for the same "hidden state" event.
The error telemetry should be fixed, but we're still going to listen on tree menus.

Discussion:
get onDidChangeSelection(): Event<ITreeEvent<T>> { return Event.map(this.tree.onDidChangeSelection, asTreeEvent); } get onKeyDown(): Event<KeyboardEvent> { return this.tree.onKeyDown; } <ins> get onMouseOver(): Event<ITreeMouseEvent<T>> { return Event.map(this.tree.onMouseOver, asTreeMouseEvent); } </ins> get onMouseClick(): Event<ITreeMouseEvent<T>> { return Event.map(this.tree.onMouseClick, asTreeMouseEvent); } get onMouseDblClick(): Event<ITreeMouseEvent<T>> { return Event.map(this.tree.onMouseDblClick, asTreeMouseEvent); } get onContextMenu(): Event<ITreeContextMenuEvent<T>> { return Event.map(this.tree.onContextMenu, asTreeContextMenuEvent); }

dnd: this.treeViewDnd, overrideStyles: getLocationBasedViewColors(this.viewLocation).listOverrideStyles }) as WorkbenchAsyncDataTree<ITreeItem, ITreeItem, FuzzyScore>); <ins> this.treeDisposables.add(this.tree.onMouseOver(e => { if (e.element) { this.tree?.rerender(e.element); } })); this.treeDisposables.add(this.tree.contextKeyService.onDidChangeContext(e => { const selection = this.tree?.getSelection(); if (selection?.length) { selection.map(item => this.tree?.rerender(item)); } const focus = this.tree?.getFocus(); if (focus?.length) { focus.map(item => this.tree?.rerender(item)); } })); </ins> this.treeDisposables.add(this.tree); treeMenus.setContextKeyService(this.tree.contextKeyService); aligner.tree = this.tree;

templateData.actionBar.context = { $treeViewId: this.treeViewId, $treeItemHandle: node.handle } satisfies TreeViewItemHandleArg; <del> const menuActions = this.menus.getResourceActions([node], templateData.elementDisposable); </del> <ins> const menuActions = this.menus.getResourceActions([node]); </ins> templateData.actionBar.push(menuActions.actions, { icon: true, label: false }); if (this._actionRunner) {

@IMenuService private readonly menuService: IMenuService ) { } <del> getResourceActions(elements: ITreeItem[], disposableStore: DisposableStore): { actions: IAction[] } { const actions = this.getActions(MenuId.ViewItemContext, elements, disposableStore); </del> <ins> getResourceActions(elements: ITreeItem[]): { actions: IAction[] } { const actions = this.getActions(MenuId.ViewItemContext, elements); </ins> return { actions: actions.primary }; }

return groups; } <del> private getActions(menuId: MenuId, elements: ITreeItem[], listen?: DisposableStore): { primary: IAction[]; secondary: IAction[] } { </del> <ins> private getActions(menuId: MenuId, elements: ITreeItem[]): { primary: IAction[]; secondary: IAction[] } { </ins> if (!this.contextKeyService) { return { primary: [], secondary: [] }; }

this.filterNonUniversalActions(primaryGroups, result.primary); this.filterNonUniversalActions(secondaryGroups, result.secondary); } <del> if (listen && elements.length === 1) { listen.add(menu.onDidChange(() => this._onDidChange.fire(element))); listen.add(menu); } else { menu.dispose(); } </del> <ins> menu.dispose(); </ins> } return { primary: this.buildMenu(primaryGroups), secondary: this.buildMenu(secondaryGroups) };