agentHost: don't subscribe to subagent chats that never spawn - #330558
Merged
roblourens merged 1 commit intoAug 13, 2026
Merged
Conversation
A `task` tool call that fails without spawning a subagent (for example when the SDK rejects it with "Maximum sub-agent depth of 4 reached") left the workbench observing a child chat URI the host never created. The host waited out its pending-subagent window and then failed the subscription: [ProtocolServer] Request 'subscribe' failed Resource not found: ahp-chat://subagent/<session>/<toolCallId> `AgentHostSessionHandler` now observes a subagent chat only while the tool can still produce one, and releases the child-chat subscription when the tool completes unsuccessfully without a subagent content block. Per-observation disposables move into a `DisposableMap` keyed by tool call so a released observation also tears down its autoruns and subscriptions. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Prevents stale subscriptions when subagent tool calls fail without creating child chats.
Changes:
- Adds a predicate for determining whether a subagent chat should remain observed.
- Tracks observations with disposable maps for immediate cleanup.
- Adds predicate and subscription-lifecycle regression tests.
Show a summary per file
| File | Description |
|---|---|
stateToProgressAdapter.ts |
Adds the observation predicate. |
agentHostSessionHandler.ts |
Releases invalid child-chat observations. |
stateToProgressAdapter.test.ts |
Tests predicate outcomes. |
agentHostChatContribution.test.ts |
Tests subscription cleanup after failure. |
Review details
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Files reviewed: 4/4 changed files
- Comments generated: 0
- Review effort level: Balanced
roblourens
marked this pull request as ready for review
August 12, 2026 22:56
roblourens
enabled auto-merge (squash)
August 12, 2026 22:56
Bhavya U (bhavyaus)
approved these changes
Aug 13, 2026
roblourens
deleted the
roblou/agents/log-analysis-error-fix-prioritization-b008581c
branch
August 13, 2026 01:47
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found while scanning recent Insiders logs for actionable errors.
Issue
A
tasktool call that fails without spawning a subagent left the workbench subscribed to a child chat URI the host never created. The host waited out its pending-subagent window (15s) and then failed the subscription:The client saw the matching failure:
The underlying tool failure was legitimate and self-describing — the SDK rejected the nested delegation:
So the agent behaved correctly; the client just kept observing a child chat that was never going to exist, producing a misleading
Resource not founderror.Root cause
AgentHostSessionHandler._tryObserveSubagentToolCallbegan observing any recognized subagent tool once it reachedRunningorCompleted, and never reconsidered that decision. A subagent-spawning tool briefly passes throughRunning, so the observation started before the depth-limit failure arrived and was never released.Fix
shouldObserveSubagentChatinstateToProgressAdapter.ts: observe while the tool isRunning, and after completion only when it actually has a subagent content block or succeeded (preserving legacy/restored snapshots that carry no content).AgentHostSessionHandlernow releases the child-chat observation when a subagent tool completes unsuccessfully without a subagent content block, instead of holding a subscription to a chat that will never exist.DisposableMapkeyed by tool call, so releasing an observation also tears down its autoruns and chat subscription.Live and nested subagents are unaffected: they keep their subscription from the moment the tool starts running.
Tests
Two regressions, both at the layer that owns the behavior (no E2E fixture needed — this is a workbench-side decision, not host/AHP behavior):
stateToProgressAdapter.test.ts— the predicate observes running/successful tools and a failed tool that produced a child, but not a failed tool without one.agentHostChatContribution.test.ts— end-to-end through the handler: the child chat subscription is live while the tool runs, and released after the failed completion. This one fails without the handler change.Validation
./scripts/test.sh --grep "subagent"over both files: 21 passingstateToProgressAdapter.test.ts: 131 passingnpm run typecheck-client: clean(Written by Copilot)