Repository navigation
Description
Summary
On the prerelease channel (1.0.81-4, 1.0.81-5), the terminal UI stops
consuming runtime events at the moment a turn launches a parallel block of
subagents. The Rust runtime is unaffected and keeps working — subagents
continue making model calls for minutes afterwards and their results are
persisted to the session store — but the terminal never repaints again, accepts
no keyboard input, and scrollback is frozen.
The process is left idle, not spinning: 0 CPU ticks over a 5s sample,
State: S (sleeping), wchan: futex_wait_queue_me, with no busy child
processes. It never recovers and does not exit on its own.
Reproduced 3 times in one evening across independent sessions.
Environment
- Copilot CLI
1.0.81-5(also seen on1.0.81-4) — prerelease channel - Node.js v22.21.1, Linux x64
- Several MCP servers configured (stdio + http)
Steps to reproduce
- Run a workflow where the top-level agent invokes a custom agent via
task. - Have that custom agent fan out to 2–3 subagents of its own in a single
parallel block (i.e. multipletaskcalls issued in one turn). - Observe the terminal at the moment the parallel block is launched.
Total concurrency at failure was 3–4 simultaneous subagents. Sequential
subagent execution has not reproduced it.
Evidence
1. The UI log stops at a turn boundary, always with the same event triple.
The final lines in every frozen session:
[WARNING] useTimeline: skipping unprocessable event type=model.response: Error: Unhandled event type in timeline: model.response
[WARNING] useTimeline: skipping unprocessable event type=model.turn_ended: Error: Unhandled event type in timeline: model.turn_ended
[WARNING] useTimeline: skipping unprocessable event type=model.messages_snapshot: Error: Unhandled event type in timeline: model.messages_snapshot
2. The timeline reducer cannot handle any model.* event. These warnings
are continuous throughout normal operation, thousands per session — one per
runtime event. Counts scale directly with subagent usage (0–260 in ordinary
sessions; 2,504 in a heavy multi-agent session). This looks like event types
emitted by the runtime that the TUI timeline reducer does not know about, i.e.
a skew between the runtime and the UI layer within the same build.
Observed types: model.message, model.turn_started, model.turn_ended,
model.model_call_started, model.model_call_success,
model.captured_assignment_context, model.tool_execution, model.response,
model.messages_snapshot.
3. The runtime continues after the UI dies. Per-call usage rows recorded in
the local session store, cross-referenced with the last UI log line:
| Session | Last UI event | Runtime kept working until | Peak concurrent subagents |
|---|---|---|---|
| A | T+0 | — | 3 (reached that same minute) |
| B | T+0 | T+8min | 4 |
| C | T+0 | T+2min or more | 4 (fan-out began T+1min) |
In session B the subagents ran to completion and their results were persisted;
only the UI was lost. copilot --resume <session-id> recovers the session,
which confirms the runtime state is intact.
Expected
The UI keeps rendering and accepting input while subagents run in parallel, or
at minimum fails loudly rather than silently detaching from the event stream.
Actual
UI silently stops consuming events. Terminal appears hung; the only recovery is
killing the process and resuming the session.
Secondary issue: frozen sessions ignore SIGTERM and can leave a spinning zombie
- All four affected processes ignored
SIGTERMand requiredSIGKILL. - One process that had begun disposal never exited, logging this once per
second indefinitely (grew its log to 656 KB before it was killed):
[ERROR] SessionClient poll loop error (will retry): Error: Cannot invoke native session after disposal has started
[ERROR] SessionClient background task refresh failed (continuing) [phase=pre-dispatch cursor=… attempts=2
Over one session these accumulated to 10 simultaneous long-lived CLI processes,
none of which could be shut down normally.
Workaround
Force subagents to run sequentially rather than in parallel blocks, and pin to
the stable channel (COPILOT_AUTO_UPDATE=false with a stable version installed
via npm).
Activity
MilkyWay008 commentedon Aug 21, 2026
The
useTimeline: skipping unprocessable event type=model.responsewarnings are the real tell, the reducer just doesn't have a branch for any of the model.* events so the whole timeline pipeline stalls when a parallel block kicks off. Runtime keeps working, only the UI detaches. Until a patch lands, avoiding parallel subagent blocks or dropping back to a release build dodges it, and you'll want SIGKILL since the frozen process ignores the polite one.bullmastiffo commentedon Aug 26, 2026
Environment
I can reproduce this repeatedly with Copilot CLI 1.0.81-3 on WSL2 Linux
x86_64 under tmux 3.4. A resumed interactive session becomes permanently
stuck on "Working" while waiting for a task/background subagent.
This is a true hang, not only a misleading status indicator:
foreground process group.
despite substantial later activity still being visible in the TUI.
wrapper app continued recording successful keepalives.
bullmastiffo commentedon Aug 26, 2026
it's starting to be unusable :(
Report: 2026-08-26 fresh-session reproduction
This is a second, independently observed hang on the same day. Unlike the
earlier occurrence, this one began in a fresh interactive session rather than
a resumed session. No prompt text, task arguments, repository information, or
private paths are included below.
Environment
The affected pane remained attached to the correct foreground process group.
tmux remained responsive from other panes, and the custom wrapper continued
successful session keepalives after Copilot stopped producing events or logs.
Timeline
All local timestamps are CEST (UTC+2).
assistant.messageevent.tool.execution_completeevent, for an unrelated completed tool call.Copilot's event journal and process log therefore became silent within about
four seconds of each other, while the outer process remained healthy for more
than three additional hours.
Missing lifecycle events
The event journal contained 119 unique
tool.execution_startrecords but only117 unique
tool.execution_completerecords. It contained foursubagent.startedrecords but only two terminalsubagent.completedorsubagent.failedrecords.call_jHpt...64uu)tool.execution_start,subagent.startedtool.execution_complete,subagent.completed/failedcall_Aqmu...JtNv)tool.execution_start,subagent.startedtool.execution_complete,subagent.completed/failedNo task arguments, descriptions, prompt text, or subagent output were retained
in this report.
Process snapshot during the hang
CPU time, write I/O, and voluntary/involuntary context-switch counts did not
advance across three samples. Only a small amount of read accounting changed,
consistent with passive pipe or socket activity. Two pane captures taken 15
seconds apart had identical hashes. Esc, double-Esc, and Ctrl-C did not
interrupt the operation or restore the prompt.
This was not CPU saturation or memory exhaustion. Network connectivity was not
generally lost: three connections remained established, and the response
WebSocket had connected successfully immediately before the final operation.
Log and journal state
There was no panic, HTTP 429/rate-limit response, HTTP 5xx response, timeout
error, or WebSocket disconnect at the hang boundary. Earlier normal
WebSocket-idle closures had recovered successfully.
Two startup-only diagnostics were present:
Both occurred before the hang boundary; neither coincided with the event/log
cutoff. Some successful startup and IDE-connection messages were emitted at
error severity, so severity alone was not used to classify failures.
Assessment
The strongest signature is two subagents that started without completion or
failure events, paired with two parent task calls that started without tool
completion events. Copilot then stopped writing both its event journal and
process log while sleeping indefinitely in a futex wait. The terminal,
foreground process group, sockets, tmux server, and outer custom wrapper all
remained alive.
This is consistent with an internal task-completion/event-consumption stall or
deadlock rather than a tmux input or rendering issue. It most closely resembles
GitHub issues #4225 and #4533. The unreaped custom-wrapper children may also be
relevant to #4385, although the missing lifecycle events are the more direct
correlation in this reproduction.
hcoona commentedon Aug 28, 2026
Additional RCA: subagent completion is lost after a two-choice
stopresponseI captured another hang after resuming a persisted session on Copilot CLI
1.0.81-3with debug logging enabled. This occurrence did not use/restartafter the resume. It appears related to this issue, but the evidence places the failure below the terminal renderer: the model response reaches the native runtime, and the runtime then fails to emit the terminal lifecycle events required to unwind the nested task chain.Trigger and control case
The top-level agent dispatched a custom agent, which led to nested
taskdispatches reaching the enforced maximum subagent depth of four. Attempts to exceed that depth returned the expectedMaximum sub-agent depth of 4 reachederror.Two sibling subagents then diverged:
stopchoice withphase: final_answer. The runtime emittedassistant.message,subagent.completed, and the parenttool.execution_completenormally.stopchoices in the same model response:finish_reasonphaseresponses_message_statusstopstopfinal_answercompletedFailure boundary
The
[rust:model_wire]log recorded the complete two-choice response at2026-08-28T09:36:00.961Z. After that boundary, the log contained fourassistant_reasoningtelemetry records but none of the following:assistant.messagesubagent.completedorsubagent.failedtool.execution_completeThe persisted event journal had already stopped at
2026-08-28T09:35:52.562Z. Every ancestor remained blocked waiting for the missing child completion. The process stayed alive but became quiescent: CPU time stopped advancing, and all threads were waiting in futex/epoll paths.SIGTERMdid not terminate it; recovery requiredSIGKILLfollowed by resuming the persisted session.Assessment
This narrows the likely defect to the native model-response-to-subagent-completion path. An empty terminal choice preceding a valid completed
final_answerchoice appears to leave the subagent without a terminal state. Reaching the depth limit may have contributed to producing this response shape, but the available evidence does not establish that the depth limit is required.The runtime should either select the valid completed final-answer choice or reject the response explicitly. In either case, every terminal model-response path should emit exactly one
subagent.completedorsubagent.failedevent and complete the parent task call so its ancestors can unwind.Environment
I have not attached the raw logs because they contain prompt and repository context. The structural fields above were extracted directly from the captured response and event journal; I can provide a further-redacted excerpt if needed.