You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SettingsEditor2.onConfigUpdate is an async method that awaits several long-running operations (experimental toggle data, installed-extension refresh, per-extension gallery manifest fetches, and createTocTreeForExtensionSettings). If the Settings editor is closed/disposed while one of those awaits is in flight, execution resumes and later calls this.instantiationService.createInstance(SettingsTreeModel, ...) on an already-disposed InstantiationService, which throws InstantiationService has been disposed. The throw escapes as an unhandled error (the search path onSearchInputChanged → triggerSearch → onConfigUpdate), producing the telemetry spike.
The async onConfigUpdate pattern with post-await service access is long-standing; no single commit in the regression window changed the triggering logic. The 1.132.0 spike (15.25x) most plausibly reflects increased traversal of the async extension-toggle path rather than a new defect at the crash site. Reported as pre-existing per the re-bucketing / pre-existing guidance.
Code Flow
sequenceDiagram
participant User as User / config change
participant Search as onSearchInputChanged / triggerSearch
participant Cfg as onConfigUpdate (async)
participant IS as InstantiationService
participant Crash as createInstance
User->>Search: change search / config
Search->>Cfg: await onConfigUpdate()
Note over Cfg: ⚠️ awaits gallery manifest fetches<br/>editor disposed meanwhile
Cfg->>IS: createInstance(SettingsTreeModel, ...)
Note over IS: store already disposed
IS->>Crash: 💥 _throwIfDisposed()<br/>"InstantiationService has been disposed"
L1457-L1670: onConfigUpdate awaits getExperimentalExtensionToggleData, refreshInstalledExtensionsList, getManifest, createTocTreeForExtensionSettings, then this.instantiationService.createInstance(SettingsTreeModel, ...) at L1670
Repro Steps
Open the Settings editor with a query that engages the extension-toggle path (extensions with recommended settings, so gallery manifest fetches are triggered).
Type in the search box to start triggerSearch → onConfigUpdate, which begins awaiting manifest fetches (subject to EXTENSION_FETCH_TIMEOUT_MS).
Immediately close the Settings editor (or switch it out) before the awaits resolve.
When the pending awaits resolve, onConfigUpdate resumes and calls createInstance on the now-disposed InstantiationService, throwing. Because timing-dependent, slow networks / many recommended-setting extensions increase the likelihood.
How the Fix Works
Chosen approach (src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts → onConfigUpdate): add a disposed-guard immediately after the final await point (createTocTreeForExtensionSettings, L1589) and before any synchronous service access. If this._store.isDisposed is true, the method returns early, so the disposed InstantiationService is never touched. This is a use-after-dispose async race, and the correct place for the guard is at the async re-entry boundary in the owning object (the consumer that resumed after dispose) — not inside InstantiationService (fix at the re-entry site, not the shared crash site, and never by widening/silencing the base service). The existing logService.error telemetry pipeline is untouched, and no try/catch is used to swallow the error.
Alternatives considered: wrapping the createInstance call in try/catch — rejected because it would silence a real lifecycle bug at the crash site and hide the same use-after-dispose from every other consumer, instead of stopping the disposed object from being used.
Recommended Owner
@rzhao271 — settings editor area owner and recent top contributor to settingsEditor2.ts (write access, active within the last 90 days). Culprit author cascade did not apply (pre-existing); selected via file/area ownership.
Original error: ERR_API: [2026-08-11T15:49:50.625Z] create pull request in microsoft/vscode failed (attempt 1)
Original error: Validation Failed: {"resource":"PullRequest","code":"custom","field":"fork_collab","message":"fork_collab Fork collab can't be granted by someone without permission"} - https://docs.github.com/rest/pulls/pulls#create-a-pull-request
Retryable: false
Suggestion: This error cannot be resolved by retrying. Please check the error details and fix the underlying issue.
To create the pull request manually:
gh pr create --title "fix: guard against disposed InstantiationService in Settings editor search (fixes #330277)" --base main --head vscodebot-pr:fix/settings-editor-disposed-race-f4f733eb0484a0ce --repo microsoft/vscode
Show patch (31 lines)
From 9fa115766689a6d0803779561f83d1eb3ebd0941 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Tue, 11 Aug 2026 15:41:05 +0000
Subject: [PATCH] fix settings editor disposed race
---
.../contrib/preferences/browser/settingsEditor2.ts | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts
index 604caadb715..caadcabe0bc 100644
--- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts+++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts@@ -1588,6 +1588,13 @@ export class SettingsEditor2 extends EditorPane {
resolvedSettingsRoot.children!.push(await createTocTreeForExtensionSettings(this.extensionService, extensionSettingsGroups, filter));
+ // The editor may have been disposed while awaiting the async work above+ // (e.g. extension manifest fetches). Bail out before touching services+ // like the InstantiationService, which throws once disposed.+ if (this._store.isDisposed) {+ return;+ }+
resolvedSettingsRoot.children!.unshift(getCommonlyUsedData(groups));
if (toggleData && setAdditionalGroups) {
--
2.54.0
Summary
SettingsEditor2.onConfigUpdateis anasyncmethod that awaits several long-running operations (experimental toggle data, installed-extension refresh, per-extension gallery manifest fetches, andcreateTocTreeForExtensionSettings). If the Settings editor is closed/disposed while one of those awaits is in flight, execution resumes and later callsthis.instantiationService.createInstance(SettingsTreeModel, ...)on an already-disposedInstantiationService, which throwsInstantiationService has been disposed. The throw escapes as an unhandled error (the search pathonSearchInputChanged → triggerSearch → onConfigUpdate), producing the telemetry spike.Fixes #330277
Recommended reviewer:
@rzhao271Culprit Commit
onConfigUpdatepattern with post-awaitservice access is long-standing; no single commit in the regression window changed the triggering logic. The 1.132.0 spike (15.25x) most plausibly reflects increased traversal of the async extension-toggle path rather than a new defect at the crash site. Reported as pre-existing per the re-bucketing / pre-existing guidance.Code Flow
sequenceDiagram participant User as User / config change participant Search as onSearchInputChanged / triggerSearch participant Cfg as onConfigUpdate (async) participant IS as InstantiationService participant Crash as createInstance User->>Search: change search / config Search->>Cfg: await onConfigUpdate() Note over Cfg: ⚠️ awaits gallery manifest fetches<br/>editor disposed meanwhile Cfg->>IS: createInstance(SettingsTreeModel, ...) Note over IS: store already disposed IS->>Crash: 💥 _throwIfDisposed()<br/>"InstantiationService has been disposed"Affected Files
src/vs/platform/instantiation/common/instantiationService.ts_throwIfDisposed, L119createInstance(from stack)src/vs/workbench/contrib/preferences/browser/settingsEditor2.tsonConfigUpdateawaitsgetExperimentalExtensionToggleData,refreshInstalledExtensionsList,getManifest,createTocTreeForExtensionSettings, thenthis.instantiationService.createInstance(SettingsTreeModel, ...)at L1670Repro Steps
triggerSearch → onConfigUpdate, which begins awaiting manifest fetches (subject toEXTENSION_FETCH_TIMEOUT_MS).onConfigUpdateresumes and callscreateInstanceon the now-disposedInstantiationService, throwing. Because timing-dependent, slow networks / many recommended-setting extensions increase the likelihood.How the Fix Works
Chosen approach (
src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts→onConfigUpdate): add a disposed-guard immediately after the finalawaitpoint (createTocTreeForExtensionSettings, L1589) and before any synchronous service access. Ifthis._store.isDisposedis true, the method returns early, so the disposedInstantiationServiceis never touched. This is a use-after-dispose async race, and the correct place for the guard is at the async re-entry boundary in the owning object (the consumer that resumed after dispose) — not insideInstantiationService(fix at the re-entry site, not the shared crash site, and never by widening/silencing the base service). The existinglogService.errortelemetry pipeline is untouched, and notry/catchis used to swallow the error.Alternatives considered: wrapping the
createInstancecall intry/catch— rejected because it would silence a real lifecycle bug at the crash site and hide the same use-after-dispose from every other consumer, instead of stopping the disposed object from being used.Recommended Owner
@rzhao271— settings editor area owner and recent top contributor tosettingsEditor2.ts(write access, active within the last 90 days). Culprit author cascade did not apply (pre-existing); selected via file/area ownership.Note
This was originally intended as a pull request, but PR creation failed. The changes have been pushed to the branch
fix/settings-editor-disposed-race-f4f733eb0484a0ce.Original error: ERR_API: [2026-08-11T15:49:50.625Z] create pull request in microsoft/vscode failed (attempt 1)
Original error: Validation Failed: {"resource":"PullRequest","code":"custom","field":"fork_collab","message":"fork_collab Fork collab can't be granted by someone without permission"} - https://docs.github.com/rest/pulls/pulls#create-a-pull-request
Retryable: false
Suggestion: This error cannot be resolved by retrying. Please check the error details and fix the underlying issue.
To create the pull request manually:
gh pr create --title "fix: guard against disposed InstantiationService in Settings editor search (fixes #330277)" --base main --head vscodebot-pr:fix/settings-editor-disposed-race-f4f733eb0484a0ce --repo microsoft/vscodeShow patch (31 lines)