microsoft / microsoft/vscode

Sessions are filtered out of the list in a remote window: working directories are compared without unwrapping their agent-host URIs

Open
#330,979 4 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.