fix: guard against undefined element in BannerPart.show() (fixes #314441)#314524
fix: guard against undefined element in BannerPart.show() (fixes #314441)#314524vs-code-engineering[bot] wants to merge 2 commits intomainfrom
Conversation
) BannerPart.show() can be called before createContentArea() initializes this.element, causing a TypeError when clearNode(this.element) is called. This happens in the Agents/Sessions product where workspace trust events fire before the banner part DOM is created. Add a guard clause to return early if this.element is not yet initialized. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Base:
|
There was a problem hiding this comment.
Pull request overview
This PR tries to stop BannerPart.show() from crashing when it is invoked before the banner DOM has been created, a timing issue exposed by the Agents/Sessions startup path.
Changes:
- Adds an early guard in
BannerPart.show()whenthis.elementis still undefined. - Aims to avoid the
clearNode(this.element)crash during early workbench startup.
Show a summary per file
| File | Description |
|---|---|
src/vs/workbench/browser/parts/banner/bannerPart.ts |
Adds a null/undefined guard at the start of show() to avoid touching the banner DOM before initialization. |
Copilot's findings
- Files reviewed: 1/1 changed files
- Comments generated: 1
| return; | ||
| } | ||
|
|
||
| if (item.id === this.item?.id) { |
There was a problem hiding this comment.
Good catch — addressed. The guard now stores the item as pendingItem and createContentArea() renders it once the DOM element is ready. This ensures the restricted-mode banner always appears even when show() is called before layout.
Generated by errors-fix-driver · ● 3.7M
Follow-up: Review Comment AnalysisTrigger: cron_review_comments Review Comment from
|
Follow-up: Automated Fixes AppliedTrigger: cron_review_comments Changes Made
Applied Diffdiff --git a/src/vs/workbench/browser/parts/banner/bannerPart.ts b/src/vs/workbench/browser/parts/banner/bannerPart.ts
--- a/src/vs/workbench/browser/parts/banner/bannerPart.ts
+++ b/src/vs/workbench/browser/parts/banner/bannerPart.ts
@@ -58,6 +58,7 @@
private item: IBannerItem | undefined;
+ private pendingItem: IBannerItem | undefined;
private visible = false;
@@ -91,6 +92,13 @@
BannerFocused.bindTo(scopedContextKeyService).set(true);
+ // Render any item that was queued before the content area was created
+ if (this.pendingItem) {
+ const item = this.pendingItem;
+ this.pendingItem = undefined;
+ this.show(item);
+ }
+
return this.element;
}
@@ -180,6 +188,7 @@
show(item: IBannerItem): void {
if (!this.element) {
+ this.pendingItem = item;
return;
}Remaining Items
|
Address review feedback: instead of silently dropping the banner request when this.element is undefined, store it as pendingItem and render it once createContentArea() initializes the DOM element. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
BannerPart.show()crashes withTypeError: Cannot read properties of undefined (reading 'firstChild')when called beforecreateContentArea()has initializedthis.element. This occurs in the Agents/Sessions product where workspace trust events fire before the banner part DOM element is created, affecting 20 users across all platforms.Fixes #314441
Recommended reviewer:
@bpaseroCulprit Commit
This is a latent bug exposed by the Agents/Sessions product's different startup timing. The
show()method never guarded againstthis.elementbeing undefined. The Agents window has a different lifecycle where workspace trust events can fire before layout callscreateContentArea(). Commit76cfc09by@sandy081(Apr 27) modified workspace trust handling for Sessions, potentially changing the timing that now exposes this race.Code Flow
sequenceDiagram participant WTrust as "WorkspaceTrustManagementService" participant UXHandler as "WorkspaceTrustUXHandler" participant Banner as "BannerPart" participant DOM as "dom.clearNode" WTrust->>UXHandler: onDidChangeTrust fires UXHandler->>Banner: bannerService.show(bannerItem) Note over Banner: this.element is undefined<br/>createContentArea not called yet Banner->>DOM: clearNode(this.element) Note over DOM: TypeError: Cannot read properties<br/>of undefined reading firstChildAffected Files
src/vs/workbench/browser/parts/banner/bannerPart.tssrc/vs/workbench/contrib/workspace/browser/workspace.contribution.tssrc/vs/workbench/services/workspaces/common/workspaceTrust.tsRepro Steps
onDidChangeTrustbefore layout completesBannerPart.show()is called whilethis.elementis still undefinedclearNode(this.element)How the Fix Works
Chosen approach (
src/vs/workbench/browser/parts/banner/bannerPart.ts→show()): Added a guard clauseif (!this.element)at the top of theshow()method that stores the item aspendingItem. IncreateContentArea(), after the DOM element is initialized, any pending item is rendered viathis.show(pendingItem). This ensures the banner always appears even whenshow()is called before layout completes.Recommended Owner
@bpasero— owns the workbench layout andPartbase class infrastructure, includingBannerPart.errors-fix-driver — cycle 1
Trigger: cron_review_comments · Head:
510491a661ae72c872d26df2f0b839cd5941b16a(510491a)bannerPart.ts:186(in scope) — store pending itemPush: yes · Copilot rerequested: ok
Ready gate: CI was green on previous head; waiting for new checks on pushed commit before marking ready.
errors-fix-driver — cycle 2
Trigger: cron_check_failed · Head:
6c19f80f6d1fe23a22220171fdb10925420e9fa1(6c19f80)bannerPart.ts:195macOS / Electron(likely transient)actions:writepermission); 25/26 checks green510491a(old head); not re-requesting since no new push this cyclePush: no (no code changes needed) · Copilot rerequested: no (no push)
Ready gate: not met — 1 CI failure (
macOS / Electron), 1 unresolved review thread (resolve blocked)