Skip to content

fix: guard statusbar updateStyles against pre-create config change (fixes #330262) #330273

Description

@vs-code-engineering

Summary

The status bar throws Assertion Failed: Argument is undefined or null. at startup on Mac, Windows and Linux (v1.133.0-insider, 326 users). StatusbarPart.updateStyles() calls assertReturnsDefined(this.getContainer()), but the newly-added configuration-change listener invokes updateStyles() while default configurations are still being registered — before the part's container (this.parent/this.element) exists — so the assertion fires.

Fixes #330262
Recommended reviewer: @hawkticehurst

Culprit Commit

Field Value
Commit eb55ea15
Author @hawkticehurst
PR #329701
Message Restore theme colors in Modern UI shell (#329701)
Why This commit added this.updateStyles(); inside the onDidChangeConfiguration listener (statusbarPart.ts:228). That listener can fire during early startup — while registerDefaultConfigurations runs — before Part.create() sets this.parent, so assertReturnsDefined(this.getContainer()) in updateStyles() receives undefined and throws.

Code Flow

sequenceDiagram
    participant Reg as ConfigurationRegistry
    participant Cfg as ConfigurationService
    participant Listener as StatusbarPart config listener
    participant Update as StatusbarPart.updateStyles
    participant Assert as assertReturnsDefined

    Reg->>Cfg: registerDefaultConfigurations (startup)
    Cfg->>Listener: onDidChangeConfiguration(MODERN_UI)
    Note over Listener: Root cause:<br/>calls updateStyles() before<br/>the part container exists
    Listener->>Update: updateStyles()
    Update->>Assert: assertReturnsDefined(getContainer())
    Note over Assert: Error thrown:<br/>Argument is undefined or null
Loading

Affected Files

File Role Evidence
src/vs/workbench/browser/parts/statusbar/statusbarPart.ts crash site L697 (from stack): const container = assertReturnsDefined(this.getContainer());
src/vs/workbench/browser/parts/statusbar/statusbarPart.ts root cause L225-L230: config listener calls this.updateStyles() unconditionally, before create() sets the container
src/vs/workbench/browser/part.ts context L78-L85: create() sets this.parent then calls updateStyles(); getContainer() returns this.parent

Repro Steps

The error is timing-dependent (fires only when a MODERN_UI default-configuration change is delivered before the status bar part is created during startup):

  1. Launch VS Code (insider) so that experimental/default settings are registered during startup.
  2. When registerDefaultConfigurations triggers an onDidChangeConfiguration event affecting workbench.modernUI before the workbench finishes creating the status bar part, updateStyles() runs with no container.
  3. The assertion Argument is undefined or null is thrown from assertReturnsDefined(this.getContainer()).

How the Fix Works

Chosen approach (statusbarPart.ts): guard the newly-added updateStyles() call in the config-change listener with if (this.element), so it only runs once the part has been created into a container. This fixes the problem at its source — the producer of the premature call — rather than at the crash site. The part already models the "not yet created" state explicitly elsewhere (e.g. addEntry checks if (!this.element) at L268), so this guard is consistent with existing lifecycle handling. When the part is later created, Part.create() calls updateStyles() (part.ts:85), so no style update is lost.

Alternatives considered:

  • Relaxing updateStyles() to use this.getContainer()?... throughout, which would weaken the invariant for the other legitimate callers that expect a container to exist and mask genuine ordering bugs.
  • Wrapping the call in try/catch, which would hide the error from telemetry instead of preventing the invalid call — rejected because errors must continue to surface.

Recommended Owner

@hawkticehurst — author of the culprit commit #329701 which introduced the updateStyles() call in the config listener, and the active owner of the Modern UI shell status bar styling work.

Generated by errors-fix · opus48 · 449.9 AIC · ⌖ 11.1 AIC · ⊞ 18.6K ·


Note

This was originally intended as a pull request, but PR creation failed. The changes have been pushed to the branch fix/statusbar-updatestyles-guard-330262-e366edab9c857081.

Original error: ERR_API: [2026-08-11T15:17:08.991Z] 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 statusbar updateStyles against pre-create config change (fixes #330262)" --base main --head vscodebot-pr:fix/statusbar-updatestyles-guard-330262-e366edab9c857081 --repo microsoft/vscode
Show patch (35 lines)
From 3da8b9bd985a61c1f2f15f97f12363f4136c0029 Mon Sep 17 00:00:00 2001
From: vscodebot <bot@example.com>
Date: Tue, 11 Aug 2026 15:08:21 +0000
Subject: [PATCH] fix: guard statusbar updateStyles against pre-create config
 change (fixes #330262)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
 .../workbench/browser/parts/statusbar/statusbarPart.ts   | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts
index b22e3171cc9..9f051cf3672 100644
--- a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts
+++ b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts
@@ -225,7 +225,14 @@ class StatusbarPart extends Part implements IStatusbarEntryContainer {
 		this._register(this.configurationService.onDidChangeConfiguration(e => {
 			if (this.getId() === Parts.STATUSBAR_PART && e.affectsConfiguration(LayoutSettings.MODERN_UI)) {
 				this._onDidChange.fire(undefined);
-				this.updateStyles();
+
+				// Only update styles once the part has been created into a
+				// container. This event can fire during early startup (e.g. when
+				// default configurations are registered) before `create` runs,
+				// at which point there is no container to style yet.
+				if (this.element) {
+					this.updateStyles();
+				}
 			}
 		}));
 	}
-- 
2.54.0

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions