coder/code-server · critical · Error

userDataPath was not provided to the browser

Error message

userDataPath was not provided to the browser

What it means

Thrown by the userDataPath getter added to BrowserWorkbenchEnvironmentImpl by the local-storage.diff patch when this.options.userDataPath is missing. The getter is now depended on by userRoamingDataHome (rewritten by the same patch to join onto userDataPath), so a missing option breaks the entire user-data path resolution and prevents workbench startup.

Source

Thrown at patches/local-storage.diff:58

+	readonly userDataPath?: string
+
 	//#endregion
 
 	//#region Profile options
Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -102,7 +102,14 @@ export class BrowserWorkbenchEnvironment
 	get logFile(): URI { return joinPath(this.windowLogsPath, 'window.log'); }
 
 	@memoize
-	get userRoamingDataHome(): URI { return URI.file('/User').with({ scheme: Schemas.vscodeUserData }); }
+	get userRoamingDataHome(): URI { return joinPath(URI.file(this.userDataPath).with({ scheme: Schemas.vscodeRemote }), 'User'); }
+
+	get userDataPath(): string {
+		if (!this.options.userDataPath) {
+			throw new Error('userDataPath was not provided to the browser');
+		}
+		return this.options.userDataPath;
+	}
 
 	@memoize
 	get argvResource(): URI { return joinPath(this.userRoamingDataHome, 'argv.json'); }
Index: code-server/lib/vscode/src/vs/workbench/services/configuration/browser/configurationService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/configuration/browser/configurationService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/configuration/browser/configurationService.ts
@@ -148,8 +148,10 @@ export class WorkspaceService extends Di
 		this.workspaceConfiguration = this._register(new WorkspaceConfiguration(configurationCache, fileService, uriIdentityService, logService));
 		this._register(this.workspaceConfiguration.onDidUpdateConfiguration(fromCache => {
 			this.onWorkspaceConfigurationChanged(fromCache).then(() => {
-				this.workspace.initialized = this.workspaceConfiguration.initialized;
-				this.checkAndMarkWorkspaceComplete(fromCache);
+				if (this.workspace) { // The workspace may not have been created yet.
+					this.workspace.initialized = this.workspaceConfiguration.initialized;

View on GitHub (pinned to 51f90a376b)

Solutions

  1. Inject userDataPath into the workbench construction options on the code-server side (the absolute user-data directory).
  2. Apply the full local-storage.diff plus the corresponding configurationService.ts hunk so the path resolves consistently.
  3. Rebuild the workbench so the new getter and option are in sync.
  4. Verify the option is non-empty (an empty string is falsy and will also throw).

Example fix

// server-side option assembly
// before: no userDataPath
// after
options.userDataPath = req.args['user-data-dir'] || defaultUserDataDir
Defensive patterns

Strategy: validation

Validate before calling

// Server-side
if (!options.userDataPath) throw new Error('userDataPath must be configured')
options.userDataPath = path.resolve(options.userDataPath)

Type guard

function hasUserDataPath(o: Record<string, unknown>): o is { userDataPath: string } {
  return typeof o.userDataPath === 'string' && o.userDataPath.length > 0
}

Try / catch

try {
  return environmentService.userDataPath
} catch (e) {
  if (/userDataPath was not provided/.test(e.message)) throw new Error('Server misconfigured: userDataPath missing')
}

Prevention

When it happens

Trigger: The workbench construction options do not include userDataPath, but the patched userRoamingDataHome getter now calls this.userDataPath. Any feature resolving user roaming data (settings, argv.json, extensions) trips the throw.

Common situations: Applying local-storage.diff without the matching code-server server-side injection of userDataPath; version mismatch where the option name changed; a fork that strips the option but keeps the getter rewrite.

Related errors


AI-assisted analysis of coder/code-server@51f90a376b (2026-08-12). Data as JSON: /api/errors/775d2d64d79c7ad5. Report an issue: GitHub.