Agent Host: create_chat hangs when target session was evicted
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
- Copilot Chat Extension Version: Agent Host / Copilot CLI 1.0.73
- VS Code Version: Code - Insiders build from 2026-07-28 (exact product version was not captured in the exported bundle)
- OS Version: macOS
- Feature (e.g. agent/edit/ask mode): Agents window / Agent Host multi-chat (`create_chat`)
- Selected model (e.g. GPT 4.1, Claude 3.7 Sonnet): Claude Opus 4.8
- Logs: Agent Host debug export captured on 2026-07-28. The bundle contains sensitive session content and can be shared privately if needed.
Steps to Reproduce:
1. Start an Agent Host session and let it become idle. Navigate away or otherwise remove its last subscription so `AgentService` evicts its in-memory session state while preserving the durable backend session.
2. From another active Agent Host session, invoke the `create_chat` server tool targeting the evicted session returned by `list_sessions`.
3. Observe that the provider creates the peer SDK session and the initial prompt is sent, but the peer chat never receives usable protocol state. A permission-requiring tool makes the hang especially clear.
Expected:
The target parent session is restored before the peer chat is created and registered. The first turn starts only after the chat has authoritative state, and any permission request is delivered to the client.
Actual:
The peer SDK session is created, but `AgentHostStateManager.addChat()` drops registration because the parent session is absent. The first turn is then dispatched and sent against an unknown chat. Progress and permission actions are dropped, leaving the SDK blocked on an unresolved permission request and the UI stuck.
Observed timeline from the debug bundle:
- The target parent session was evicted after its last unsubscribe.
- Roughly 20 seconds later, `create_chat` logged `Created additional chat ... in session ...`.
- This was immediately followed by `addChat for unknown session`, `Action for unknown chat ... chat/turnStarted`, and `Turn started for session not in state manager`.
- The peer SDK session later logged `Requesting confirmation for tool call`, but no permission response was ever recorded.
- Restoring the parent reconstructed the peer turn as cancelled/idle, while retries reached `session.send() returned` but produced no subsequent assistant events.
Root cause on latest `main`:
As of `0d66fdd49d0ecc3b2dcdd8ac0dfff9d41215d4fc` (2026-08-06), the race remains:
1. `applyCreateChatTool()` calls `listSessions()` and validates durable metadata, but does not materialize the selected session.
2. `AgentService.createChat()` invokes the provider without first calling `restoreSession()` when parent state is absent.
3. The provider successfully creates the backing chat.
4. `AgentHostStateManager.addChat()` logs and returns `undefined` for the unknown parent; the failure is ignored.
5. `_startSessionPrompt()` still dispatches `ChatTurnStarted` and routes the prompt to the provider against the unregistered chat.
The lazy peer-chat restoration work in `aa23e75a7ae` does not cover creation against an evicted parent. Existing `createChat` tests restore the parent explicitly before creating the peer chat, so this path has no regression coverage.
Suggested fix:
- Restore/materialize the parent session before provider chat creation when it is absent from the state manager.
- Treat failed chat registration as an error and dispose the newly-created provider backing instead of persisting/sending against it.
- Add a regression test that deletes/evicts parent state, calls `createChat()` directly without an explicit restore, starts the prompt, and verifies chat registration plus permission delivery.
Contributor guide
Assessment
This issue has not been assessed yet.