Skip to content

fix(terminal): catch ENOPRO in getCwdResource when file:// provider absent in VS Code web#317780

Merged
meganrogge merged 2 commits into
microsoft:mainfrom
mutl3y:fix/terminal-getcwdresource-web-enopro
Jun 5, 2026
Merged

fix(terminal): catch ENOPRO in getCwdResource when file:// provider absent in VS Code web#317780
meganrogge merged 2 commits into
microsoft:mainfrom
mutl3y:fix/terminal-getcwdresource-web-enopro

Conversation

@mutl3y

@mutl3y mutl3y commented May 21, 2026

Copy link
Copy Markdown
Contributor

Problem

Fixes #317329 (related — same deployment scenario, different subsystem)

When using VS Code Server (server-linux-x64-web) accessed via a browser, calling getCwdResource() on a terminal instance throws:

Error: No file system provider found for resource 'file:///workspace' (ENOPRO)

This surfaces as a failure on every Copilot agent terminal tool invocation (the agent host calls getCwdResource() to resolve the working directory before running a shell command). Any other caller that relies on this method is similarly broken.

Root cause

getCwdResource() in terminalInstance.ts has two branches:

if (this.remoteAuthority) {
    resource = await this._pathService.fileURI(cwd);  // remote-aware ✅
} else {
    resource = URI.file(cwd);                          // Electron/desktop only ❌
}

In a self-hosted server-linux-x64-web deployment without an explicit remoteAuthority header, this.remoteAuthority is falsy from the terminal's perspective. The else branch fires, producing a file:///workspace URI. The browser FileService has no file:// provider registered — only the remote provider — so _fileService.exists(resource) throws ENOPRO.

This else branch is desktop/Electron-only code: in a correct remote-web context remoteAuthority would be set and _pathService.fileURI() would be used instead.

Fix

Wrap the function body in try/catch so that provider errors (ENOPRO or otherwise) return undefined, allowing callers to fall back to the default CWD rather than propagating the error. The existing logic is preserved — only the error path is changed.

async getCwdResource(): Promise<URI | undefined> {
    const cwd = this.capabilities.get(TerminalCapability.CwdDetection)?.getCwd();
    let resource: URI;
    try {
        if (this.remoteAuthority) {
            resource = await this._pathService.fileURI(cwd);
        } else {
            resource = URI.file(cwd);
        }
        if (await this._fileService.exists(resource)) { return resource; }
    } catch {
        // FileService provider not available for this URI scheme (e.g. file:// in
        // VS Code web where only the remote provider is registered).
        return undefined;
    }
    return undefined;
}

Testing

Verified against a running server-linux-x64-web instance (v1.121.0, commit f6cfa2ea) in a containerised deployment:

  • Before: Copilot agent terminal tool fails on every invocation with ENOPRO
  • After: Terminal tool executes successfully; getCwdResource returns undefined and the tool falls back to the default CWD

Notes

  • Only one file changed: src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
  • This is independent of PR Fix secret storage persistence in VS Code Server web #317333 (secret storage key minting) — different subsystem, different file
  • A more complete fix would detect the web context and always route through _pathService.fileURI(); this PR takes the minimal safe approach of catching the error
Copilot AI review requested due to automatic review settings May 21, 2026 14:32
@mutl3y mutl3y marked this pull request as ready for review May 21, 2026 14:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens the terminal instance working-directory URI resolution in VS Code web/server scenarios by preventing getCwdResource() from throwing when the FileService cannot handle the produced URI (notably when a file:// provider is absent), allowing callers (including agent terminal tools) to fall back gracefully.

Changes:

  • Wrap TerminalInstance.getCwdResource() URI creation/existence validation in try/catch.
  • Return undefined instead of propagating provider-related errors (e.g. ENOPRO) from fileService.exists.
Comment thread src/vs/workbench/contrib/terminal/browser/terminalInstance.ts Outdated
Comment thread src/vs/workbench/contrib/terminal/browser/terminalInstance.ts Outdated
…e on VS Code web

In VS Code Server (server-linux-x64-web) accessed via browser, the terminal's
remoteAuthority is falsy so URI.file() is produced in getCwdResource(). The
browser FileService has no file:// provider registered (only the remote
provider), causing ENOPRO on every Copilot agent tool call.

Replace the blanket try/catch with a targeted canHandleResource() guard so that
provider errors are detected before calling exists(), while other genuine errors
from fileURI()/URI.file() remain surfaced to callers.

Also adds a unit test covering the ENOPRO / provider-absent scenario.

Discovered during deployment: workbench.web.main.internal.js (the server-side
agentHost bundle) requires the same fix as workbench.js (the browser-side
bundle), since the agentHost process loads the server bundle independently.

Fixes: getCwdResource() returning ENOPRO when file:// provider absent
Addresses: Copilot PR review feedback on blanket catch scope and missing test
@mutl3y mutl3y force-pushed the fix/terminal-getcwdresource-web-enopro branch from b90e189 to 68619df Compare May 23, 2026 16:03
@vs-code-engineering

Copy link
Copy Markdown
Contributor

📬 CODENOTIFY

The following users are being notified based on files changed in this PR:

@anthonykim1

Matched files:

  • src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
  • src/vs/workbench/contrib/terminal/test/browser/terminalInstance.test.ts
@meganrogge meganrogge enabled auto-merge (squash) June 5, 2026 17:57
@meganrogge meganrogge added this to the 1.124.0 milestone Jun 5, 2026
@meganrogge meganrogge merged commit 0712539 into microsoft:main Jun 5, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

5 participants