[Remote-SSH][Agent Host] Changed-file diff treats remote Linux file: URI as a local Windows path
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
Does this issue occur when all extensions are disabled?: No / not applicable. The reproducer depends on the built-in Agent Host / Codex changed-files workflow, so disabling that functionality removes the affected code path rather than meaningfully testing it.
- VS Code Version: 1.136.1, commit `a44adf7f53e00964ab890f9f8758a334f1fc15bc`
- OS Version: Windows 11 x64 (`Windows_NT 10.0.26200`)
- Remote environment: Linux / Ubuntu via VS Code Remote-SSH
- Remote Agent Host / Codex package: `0.146.0`
Steps to Reproduce:
1. Run VS Code on Windows.
2. Connect to a Linux machine using Remote-SSH.
3. Open a folder on the remote machine.
4. Start a Codex / Agent Host chat session.
5. Ask the agent to make a small edit to an existing file in the remote workspace.
6. Wait for the response containing the `1 file changed` summary.
7. Click the changed file in that summary.
### Actual result
The remote POSIX file path is treated as a local Windows `file:` resource.
For example, the real remote file:
/var/www/example/web/project/config.php
is displayed / opened on the Windows side as:
\var\www\example\web\project\config.php
and VS Code fails with an error similar to:
Unable to read file '\var\www\example\web\project\config.php'
(Error: Unable to resolve nonexistent file '\var\www\example\web\project\config.php')
The file itself exists and opens normally through the Remote-SSH workspace.
The correct workspace resource is of the form:
vscode-remote://ssh-remote+my-host/var/www/example/web/project/config.php
### Expected result
Clicking the changed file should open its diff using the Remote-SSH filesystem provider.
The modified side should resolve to the remote workspace resource instead of being interpreted as a local Windows filesystem path.
### Investigation
I traced the issue to the Agent Host URI mapping.
In:
`src/vs/platform/agentHost/common/agentHostUri.ts`
the current implementation contains:
function wrapAgentHostUri(originalUri: URI, connectionAuthority: string, contentRef: boolean): URI {
if (connectionAuthority === 'local' && originalUri.scheme === Schemas.file) {
return originalUri;
}
// ...
}
The same source also documents the assumption behind the `local` authority:
/**
* Authority of the in-process agent host. It always runs on the same
* machine — and therefore the same operating system — as the client.
*/
export const LOCAL_AGENT_HOST_AUTHORITY = 'local';
In this Remote-SSH scenario, however, a POSIX URI such as:
file:///var/www/example/web/project/config.php
produced by the Agent Host eventually reaches the Windows renderer unchanged.
Windows then interprets it as a local filesystem resource and converts it to:
\var\www\example\web\project\config.php
The per-response changed-files provider also constructs the modified resource through `toAgentHostUri(...)`.
### Git / snapshot side is not the cause
I also verified the original side of the diff.
The `git-blob:` resource used for the original version is readable. A `resourceRead` request succeeds and returns the expected content.
A subsequent `createResourceWatch` request against the immutable `git-blob:` resource may fail with `Resource not found`, but this is separate from the modified-file failure.
The underlying Git commit, repository-relative path, and `git show :` lookup all work correctly.
### Working diagnostic workaround
I tested a local modification to the compiled VS Code workbench bundle.
For the affected remote workspace path only, instead of returning the raw `file:` URI, I mapped it to the active Remote-SSH resource:
URI.from({
scheme: "vscode-remote",
authority: "ssh-remote+my-host",
path: originalUri.path,
query: originalUri.query,
fragment: originalUri.fragment
})
Before this change:
file:///var/www/example/web/project/config.php
->
\var\www\example\web\project\config.php
->
Unable to resolve nonexistent file
After this change and a full VS Code restart:
vscode-remote://ssh-remote+my-host/var/www/example/web/project/config.php
->
diff opens correctly
No other change was required.
This is only a diagnostic workaround, not a proposed final architectural fix. The proper fix likely needs to map Agent Host `file:` resources back into the current Remote-SSH client resource space instead of assuming that `connectionAuthority === "local"` means the renderer can directly access the same filesystem.
### Relevant source paths
The affected changed-file summary is backed by the Agent Host response-file changes provider, which eventually maps the modified file through `toAgentHostUri(...)`.
Relevant source files include:
src/vs/platform/agentHost/common/agentHostUri.ts
src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostResponseFileChanges.ts
src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatChangesSummaryPart.ts
### Related issue
There is an existing OpenAI Codex issue with a very similar user-visible failure in a Windows -> Remote-SSH -> Linux setup:
https://github.com/openai/codex/issues/36323
That report describes changed-file preview information working, while opening/reviewing the diff fails.
### Additional notes
The issue reproduces with a newly created Codex edit, so it is not caused by stale session data.
The remote file can be opened normally from Explorer and from the editor when accessed through its `vscode-remote://` resource.
The failure is specifically in the changed-file / diff flow when a remote Linux `file:` URI reaches the Windows renderer as a plain local file URI.
Contributor guide
Assessment
This issue has not been assessed yet.