Skip to content

webview: respect default localResourceRoots for custom editors#312492

Merged
mjbvz merged 1 commit intomicrosoft:mainfrom
maruthang:fix/issue-282495-localresourceroots
May 1, 2026
Merged

webview: respect default localResourceRoots for custom editors#312492
mjbvz merged 1 commit intomicrosoft:mainfrom
maruthang:fix/issue-282495-localresourceroots

Conversation

@maruthang
Copy link
Copy Markdown
Contributor

Fixes #282495

Problem

Per the WebviewOptions.localResourceRoots docs, if the option is left unset the webview should default to allowing the workspace folder roots plus the extension's install directory. vscode.window.createWebviewPanel honors this contract — ExtHostWebviewPanels.createWebviewPanel fills in the default before the create RPC.

Custom editors do not. The main thread builds the overlay with contentOptions: {} and then calls $resolveCustomEditor on the extension host. Because the extension host never receives a chance to fill in the default, asWebviewUri returns HTTP 401 for resources under the workspace or the extension folder unless the extension explicitly sets webview.options = { localResourceRoots: [...] }. This silently breaks custom-editor extensions that follow the documented default.

Fix

Added ExtHostWebviews.ensureDefaultContentOptions(handle, contentOptions, extension). When contentOptions.localResourceRoots is undefined, it calls $setOptions with the documented default (workspace folders + extension install directory, mirroring the logic in ExtHostWebviewPanels.createWebviewPanel). When the extension provided explicit roots — including an empty array — the helper does nothing.

MainThreadCustomEditors.$resolveCustomEditor invokes the helper from ExtHostCustomEditors immediately after createNewWebview, before the provider's resolveCustomTextEditor / resolveCustomEditor runs. Existing webview.options = ... assignments inside provider callbacks continue to work — those go through serializeWebviewOptions, which already re-applies the default.

Tests

Added three unit tests in src/vs/workbench/api/test/browser/extHostWebview.test.ts:

  • default fills in workspace folders + extension install directory when localResourceRoots is omitted
  • explicit localResourceRoots (even []) is respected — $setOptions is not called
  • with no workspace open, the default is just the extension install directory

Custom-editor flow constructs the webview overlay on the main thread
with empty contentOptions and never propagates the documented default
localResourceRoots (workspace folders + extension install directory),
so asWebviewUri returns 401 unless the extension explicitly sets
webview.options. The regular createWebviewPanel flow already applies
this default in ExtHostWebviewPanels.createWebviewPanel.

Add ExtHostWebviews.ensureDefaultContentOptions which calls $setOptions
with the documented default when localResourceRoots is absent, and
invoke it from $resolveCustomEditor right after createNewWebview.

Fixes microsoft#282495
Copy link
Copy Markdown
Collaborator

@mjbvz mjbvz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@mjbvz mjbvz merged commit aa73b3e into microsoft:main May 1, 2026
26 checks passed
@vs-code-engineering vs-code-engineering Bot added this to the 1.119.0 milestone May 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom editor webview's localResourceRoots contract is not respected

3 participants