Sessions are filtered out of the list in a remote window: working directories are compared without unwrapping their agent-host URIs
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
### Summary
In a remote window (a dev container, here) agent sessions are filtered out of the sessions list because their working directories are reported as the remote's own `file:` URIs, while the workspace folder of such a window is a `vscode-remote:` URI. The containment check that decides list membership compares scheme first, so it can never match, however identical the paths are.
This is not a subset of sessions: in the `listSessions` payloads the agent host emitted in one log directory, **all 97 distinct sessions report `file:///workspace/printstream`, and none reports the `vscode-remote:` form**. So the list is empty in that window.
### Repro
1. Open a folder in a dev container.
2. Have agent sessions whose working directory is that folder.
3. Open the sessions list.
Observed: the sessions do not appear.
Expected: sessions on this workspace folder appear.
### Cause
List membership is decided by `_isSessionInWorkspace` → `_matchesAnyFolder` ([agentHostSessionListStore.ts:395-399](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionListStore.ts#L395-L399)):
```ts
private _matchesAnyFolder(workingDirectories: readonly URI[], folders: readonly IWorkspaceFolder[]): boolean {
return workingDirectories.some(directory =>
folders.some(folder => extUriBiasedIgnorePathCase.isEqualOrParent(directory, folder.uri))
);
}
```
`isEqualOrParent` gates on the scheme before it compares anything else ([resources.ts:171-176](https://github.com/microsoft/vscode/blob/main/src/vs/base/common/resources.ts#L171-L176)):
```ts
isEqualOrParent(base: URI, parentCandidate: URI, ignoreFragment: boolean = false): boolean {
if (base.scheme === parentCandidate.scheme) {
...
}
```
so a `file:` working directory against a `vscode-remote:` folder short-circuits to `false`.
Running that matcher against the two forms this host actually emits, with the real folder URI of the window:
```js
const folder = URI.parse('vscode-remote://dev-container%2B7b22…/workspace/printstream');
const wdRemote = URI.parse('vscode-remote://dev-container%2B7b22…/workspace/printstream');
const wdFile = URI.parse('file:///workspace/printstream');
extUriBiasedIgnorePathCase.isEqualOrParent(wdRemote, folder) // true -> would list
extUriBiasedIgnorePathCase.isEqualOrParent(wdFile, folder) // false -> filtered out
wdFile.path === folder.path // true -> only the namespace differs
```
### Both forms come from the same host
The session-list summaries carry the `file:` form:
```json
{"resource":"claude:/83d5b222-…","provider":"claude","title":"Grouped toasts for print jobs",
"workingDirectories":["file:///workspace/printstream"]}
```
An opened session's state carries the `vscode-remote:` form instead — and mixes the two inside one payload, since `project.uri` stays `file:`:
```json
{"project":{"uri":"file:///workspace/printstream","displayName":"printstream"},
"workingDirectories":["vscode-remote://dev-container%2B7b22…/workspace/printstream"]}
```
I have not established why the two paths differ, and I would rather report that than guess. The candidates I can see are that the URI recorded depends on how the session was created (one started from the workbench in a remote window is handed the `vscode-remote:` URI, one started inside the container records its own `file:` path), or that a translation is applied on the state path but not on the list path. Either way, the path that decides visibility is the one receiving untranslated URIs.
### Notes on fixing
I am not opening a PR with this, because the remedies I can see are design calls rather than something to guess at:
- normalize working directories into the client's namespace before they reach the list, keeping the comparison a strict URI containment check; or
- make the list comparison namespace-aware for remote windows.
Comparing on path alone does make the sessions appear, but I would not propose it: two different remotes exposing the same path would then compare equal.
### Environment
VS Code 1.133.0 (`a5b500951314efd502d07465bd138dfbd714a960`), Windows client, dev container remote, Claude provider, single-folder window.
*AI disclosure: this issue was written with the assistance of AI.*
### Public patches and patcher scripts
[Public patch catalog and patcher scripts](https://github.com/RyanEwen/vscode-patches/blob/main/CATALOG.md) · [Source patch index](https://github.com/RyanEwen/vscode-patches/blob/main/SOURCE-PATCHES.md). The [public collection](https://github.com/RyanEwen/vscode-patches) includes the maintained patchers, rollback instructions, regression scripts, and historical snapshots. Build restrictions and exact installer coverage are documented there.
Contributor guide
Research direction
Start in src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionListStore.ts at _isSessionInWorkspace and _matchesAnyFolder, then read isEqualOrParent in src/vs/base/common/resources.ts. Reproduce in a dev container with the file: and vscode-remote: forms and inspect the session-list payloads. Done means sessions for the active remote workspace appear without treating identical paths from different remotes as equal.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript, vscode
- Domain
- developer-experience, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100