Agent Host Claude session still subscribes to obsolete untitled URI after #330761 and hangs forever
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
Does this issue occur when all extensions are disabled?: Yes. The failure is in
the core Agent Host new-session lifecycle. No extension or MCP server was
blocked; the Claude SDK and its one MCP child were both idle on `ep_poll`.
- VS Code Version: commit `645f29cc3176500b4b5762ba887cf2a7f0ffdf2c`
- OS Version: Linux x64, GitHub Codespaces
- Feature: Agents window, Agent Host / Claude provider, new-session flow
- Related: #330531, fixed by #330761
## Summary
#330761 is present in the reproducing build, but a new Claude session can still
subscribe to an obsolete `claude:/untitled-*` resource immediately before the
provider binds a different real scope. The subscription receives
`AHP_SESSION_NOT_FOUND`; the real scope never publishes an active client; and
the turn hangs indefinitely.
This is a remaining identity-remapping variant of #330531, not the
workspace-trust/eager-create ordering path fixed by #330761.
## Steps to Reproduce
This has reproduced probabilistically several times:
1. In the Agents window, create a new session with Session Target **Claude**.
2. Send the first prompt while the new session is materializing.
3. If the race loses, observe the tab remain stuck indefinitely.
Rapidly opening replacement sessions increases the probability but is not
required.
## Expected
The client must not open a wire subscription for a provisional
`:/untitled-*` resource that will be replaced during materialization.
It should await the untitled-to-real mapping and subscribe to the real backend
URI, or fail promptly with an actionable error.
## Actual
Sanitized `agenthost.log` sequence:
```text
13:13:29.220 [error] Request 'subscribe' failed
Session not found on backend: claude:/untitled-
13:13:29.222 [info] Bound chat ... to fresh conversation
for scope claude:/
```
Only **2 ms** separated the failure and the real bind.
For `claude:/` there was:
- one `Bound chat` line;
- zero `[Claude:] active client ... tools=[...]` lines;
- no entry in the session registry;
- an SDK backend left alive and idle on `ep_poll`;
- one healthy MCP child also idle on `ep_poll`.
The tab did not recover with time. Terminating only that dead SDK backend forced
the client to recover immediately.
## Why #330761 does not cover this instance
The installed source contains the `NewSession.eagerCreate()` ordering:
1. await `connection.createSession(...)`;
2. then call `connection.getSubscription(...)`.
It also waits for the eager creation task before first request dispatch. The
observed failing subscription nevertheless targeted `claude:/untitled-`,
while the provider bound `claude:/` two milliseconds later.
Retrying the same request blindly cannot work because materialization changes
the identity. The failed URI and usable URI are different.
## Suggested fix
Preferred:
1. Do not open a wire-level session subscription for
`:/untitled-*`.
2. Await the existing untitled-to-real materialization mapping.
3. Subscribe once to the mapped real backend URI.
Alternatives:
- preserve the provisional identity through materialization, so create and
subscribe address the same URI;
- on `AHP_SESSION_NOT_FOUND` for an untitled URI, await materialization and
retry against the mapped **real** URI (not the obsolete untitled URI).
## Regression test
Repeatedly create a new Agent Host Claude session and immediately send, then
assert one of:
- no `subscribe` request is ever sent for a `claude:/untitled-*` channel; or
- any provisional attempt is redirected to the mapped real URI and completes
within a bounded time.
The delayed-workspace-trust tests added by #330761 cover create-before-subscribe
ordering but not provisional-to-real identity remapping.
## Additional disambiguation
This was not MCP startup or resource exhaustion:
- one MCP process, approximately 68 MB;
- no orphaned MCP trees;
- all relevant processes idle-healthy;
- the failed subscribe preceded the real bind by 2 ms.
Contributor guide
Assessment
This issue has not been assessed yet.