Parent's text-only final message not rendered when a background subagent's turn boundary lands inside the parent turn (1.0.84-8)
Nobody has claimed this yet.
- Dominant language
- Shell
- Stars
- 11.2k
- Forks
- 1.9k
- Avg merge
- 14h 16m
- Merged PRs (30d)
- 6
Description
Summary
In interactive mode, a text-only final assistant message (no tool calls, no reasoning block) was emitted by the model, persisted to the session's events.jsonl and to the session-history store, and never painted in the terminal. The user saw the turn end with no response and asked again. The message is fully present in ~/.copilot/session-state/<id>/events.jsonl as assistant.message with content (1,768 chars), toolRequests: [], rte: true.
What is unusual about the turn: a background subagent (started earlier via task in background mode) was mid-flight, and its assistant.turn_end / assistant.turn_start events fired inside the parent's turn, immediately before the parent's final message. Those subagent turn-boundary events carry no parentToolCallId, so from the event stream they are indistinguishable from the parent's own turn boundaries. The parent's final message was on the parent's turnId (10); the UI had just seen turn_start for the subagent's turnId (70).
This looks related to but distinct from #4735 / #4450 (text before a tool call folded into "Thought for…") — here there was no tool call and no reasoning; the message was the entire turn. It is also distinct from #4533 (full UI freeze) — the UI kept working; only this one message was lost.
Version
GitHub Copilot CLI 1.0.84-8 (auto-updated; ~/.copilot/pkg/darwin-arm64/ holds 1.0.84-4 … 1.0.84-8), macOS arm64, Ghostty, model claude-fable-5.1, background subagent model gpt-5.5.
Event sequence (from events.jsonl, hook events omitted)
idx | time | type | parentToolCallId | turnId | content-len
23315 | 17:13:55.160 | user.message | - | 10 | 95
23318 | 17:13:57.104 | tool.execution_complete | toolu_01Va… | 68 | - <- background subagent
23319 | 17:13:57.274 | assistant.turn_end | - | 68 | - <- subagent turn, NO parentToolCallId
23320 | 17:13:57.277 | assistant.turn_start | - | 69 | - <- subagent turn, NO parentToolCallId
23322 | 17:13:59.512 | model.model_call_success | - | | <- parent's model call
23327 | 17:14:00.901 | assistant.message | toolu_01Va… | 69 | 0 <- subagent (encryptedContent only)
23332 | 17:14:02.952 | assistant.turn_end | - | 69 | -
23333 | 17:14:02.952 | assistant.turn_start | - | 70 | -
23334 | 17:14:06.708 | assistant.message | toolu_01Va… | 70 | 0
23338 | 17:14:52.206 | assistant.message | - | 10 | 1768 <- PARENT's final text; never rendered
23339 | 17:14:52.223 | assistant.turn_end | - | 10 | -
Other text-only final messages earlier in the same session, with subagent turns also interleaved, did render — so this is order/timing-sensitive, consistent with the timeline tracking "current turn" from the most recent assistant.turn_start and discarding a message whose turnId doesn't match.
Expected
A parent assistant.message with content and no tool requests renders as a chat message regardless of subagent turn-boundary events interleaved in the stream. Subagent assistant.turn_start/turn_end events should carry parentToolCallId (as the subagent's assistant.message and tool.execution_* events already do), so the timeline can scope them.
Impact
The user asked the same question three times because the answer was never shown; the assistant, reading its own persisted history, believed it had answered. This is a trust problem: the transcript and the screen disagree.
Reproduction (probabilistic)
- Start a long-running background
task(any model). - While it runs, ask the parent a question whose answer is a text-only reply (no tool calls).
- Repeat until the parent's reply lands within ~1s after a subagent turn boundary. In my session it hit on the third text-only reply during an active background agent.
Happy to share the sanitized events.jsonl slice privately.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by inspecting the event handling around the reproduced events.jsonl sequence and the session-history store, focusing on how the current turn is tracked across background-subagent boundaries. Reproduce the timing-sensitive case with a background task and a text-only parent reply. Done means the parent assistant.message is rendered while subagent turn boundaries remain correctly scoped.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- shell
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100