Background task notification enqueued but never delivered when the owning subagent already completed (SendMessage-resumed agent's orphaned Bash task)
Environment
- Claude Code v2.1.207, macOS (darwin 25.5.0), CLI entrypoint
- Main session running a plugin skill that orchestrates subagents (Task tool + SendMessage)
Summary
A <task-notification> for a completed background Bash task was enqueued into the main session's message queue but never dequeued/delivered, even though the session was idle and remained open for many hours afterward. The distinguishing feature of the stranded notification: the background task was started by a subagent that had already returned — the subagent was a Task-tool agent that completed, was then continued via SendMessage (harness replied "had no active task; resumed from transcript in the background"), started a run_in_background: true Bash command during that resumed run, and then completed again, orphaning the task.
Every other task notification in the same session (~25 of them, including three completion notifications for the same subagent) shows enqueue → dequeue within milliseconds-to-seconds in the session JSONL. The stranded one shows only enqueue, forever.
Event sequence (from the session JSONL, timestamps UTC)
- Main agent launches a subagent via Task; subagent completes at
07:17:15— notification enqueued and dequeued within 20 ms. Same again at07:18:08. - Main agent continues the completed subagent via
SendMessage→ result:"Agent … had no active task; resumed from transcript in the background with your message." - The resumed subagent starts
gh pr checks <N> --watchwithrun_in_background: true(task idbd48ibvdo), then ends its turn (completes). Its completion notification is delivered normally at07:27:58(enqueue07:27:58.669→dequeue07:27:58.686). - Main agent ends its turn idle, waiting for the watch task's completion notification.
- The orphaned background task completes:
queue-operation enqueuefor its<task-notification>at07:30:09.494— no dequeue ever follows. - The process is still alive: a
system/away_summaryevent is written at07:31:07.953. The session then sits idle. The terminal window stayed open for 16+ hours; the notification was never delivered and no further turn ever started.
Last two events of the transcript:
{"type":"queue-operation","operation":"enqueue","timestamp":"2026-07-11T07:30:09.494Z","content":"<task-notification>\n<task-id>bd48ibvdo</task-id>…"}
{"type":"system","subtype":"away_summary","timestamp":"2026-07-11T07:31:07.953Z",…}
Impact
Unattended multi-agent automation dies silently. In our case an issue-fixing orchestration had verified a PR's CI was green and was waiting on this one notification to merge it; the run ended with the PR unmerged and no summary, with no error anywhere. The "away" state is not the cause: three notifications were delivered normally in the minutes immediately before, equally unattended.
Expected
Either (a) the enqueued notification wakes the idle main loop like every other task notification, or (b) if notifications from tasks whose owning (completed) subagent can't receive them are intentionally dropped, they should not be enqueued into the parent's queue at all — and ideally the harness would surface a warning rather than leaving the notification permanently queued.
Repro sketch
- In a main session, launch a Task subagent and let it complete.
SendMessageto the completed agent so it resumes "from transcript in the background".- Have the resumed agent start a long-running Bash command with
run_in_background: trueand end its turn before the command exits. - Let the main agent end its turn idle. When the background command exits, its task notification is enqueued into the main session but (in our observation) never delivered.
5 Comments
Add text{mark:issue} [Down : For] , [Major to major selctions]. while Including Transcript selections . Context , ReBegin - [re- continue ]:{Start with agent selection , View-forms : <Multi-selections> , [Context-reload, Begin()]} [Dequeue-list , Enlist-encodings , Enqueue => upcoming]
Same enqueue-never-delivered failure, but on a different and much more reproducible surface: user-launched
spawn_taskchips in Desktop local-agent-mode.The OP's trigger is narrow (a
SendMessage-resumed agent's orphanedrun_in_backgroundBash task). I'm seeing the identical end symptom — a<task-notification>that the launching conversation never receives — for a plainer, higher-traffic case: you click a suggested-task chip, it spins off its own session, that session runs to completion, and the parent is never notified. In this form it isn't an edge case — across every chip I've been able to trace, the completion notification back to the launching conversation fired zero times.Evidence (git-verified outcomes, not just transcripts)
Four chips, two separate private repos (labeled Repo A / Repo B below). For each I confirmed via
git log --all/merge-base --is-ancestorwhat the spawned session actually produced, and searched the full session store for any<task-notification>carrying the chip'stask_id:| Chip
task_id| Date | Repo | What the spawned session did | Result on disk | Parent notified? ||---|---|---|---|---|---|
|
b79dfd48| 2026-07-06 | A | Fixed the target test and a real nested-worktree path bug; 1113 tests pass | committed + pushed → landed onmain| No ||
ef27e98f| 2026-07-06 | A + B | Fixed the import; xfail'd an ordering deadlock; addedpytest-timeout| committed + pushed to both → onmain| No ¹ ||
d8467435| 2026-07-07 | A | Root-caused a genuine Qt/OpenGL refcount-cycleSIGABRT; weakref fix; 1269 pass | committed + pushed → onmain, then self-cleaned its worktree | No ||
b1dc2220| 2026-07-14 | B | Completed all planned work; 112 tests pass — but never committed | left as an uncommitted diff in the worktree | No ² |0 / 4 completion notifications delivered to the launching conversation. In each parent session, the only trace of the chip is the initial
<system-reminder>"The user started your suggested background task task_… You will be notified here when it ends." — and then silence. (In three of the four the work was fine and even reachedmain; the parent just never learned it existed or finished.)¹
ef27e98f's spawned session had some live human interaction late in its life, so "not notified" there means the originating parent conversation specifically was never told — not that the user was wholly unaware.²
b1dc2220is the dangerous one — see "severity" below.This isn't new, and it predates the recent worktree-pool issues
The earliest instance I can find is 2026-05-30 — roughly six weeks before #75911/#77609 — where the user is reduced to guessing from the absence of a running process: "The chip was launched, and actually I don't see it running any more so I guess it finished?" So the chip-completion notification path appears to have been broken for a long time, across at least one reminder-format change (the "started your suggested background task" wording only appears in my data from 2026-07-05 onward, but the missing-notification symptom predates it).
Why I think it's the same underlying defect as this issue
The OP nails the mechanism as enqueue with no dequeue when the notification's intended recipient isn't in a state to receive it. A
spawn_taskchip is exactly that shape at a coarser grain: the "owner" is a separate spawned session that has already ended, and the parent is idle waiting. If the delivery gap is really "notifications whose owner has completed are enqueued but never dequeued," then user-launched chips are the most common way to hit it, not a corner case. Happy to be told the chip path is a distinct code path from the orphaned-Bash path — in which case I'll file it as its own issue — but the symptom, the "enqueue-only" fingerprint, and the "owner already completed" precondition all line up.Severity corollary (why the
b1dc2220row matters)When the chip does commit its work (rows 1–3), the missing notification is "merely" an observability failure: the result is safely on
main, you just aren't told. When the chip finishes without committing (row 4), the missing notification becomes silent data loss — the work exists only as an on-disk diff, with no signal that it's there. That case was recovered only because a human later noticed the stale worktree; a routinegit checkout/resetor a worktree reclaim would have destroyed it with no trace. It gets worse still when combined with #77609 (the pool handing a chip an already-active worktree), which is exactly what happened to us — the uncommitted work was sitting in a directory a different session was actively driving git against. Filed separately: #77661. See also #71773 (parent cannot observe spawned children) and #20754.I can share session UUIDs, per-chip reflogs, and the
merge-baseproofs if useful.Parent main-log : log.screen('access') : spawn-tasks-Based on
<sessions-active , Agents-running>
Informal : Base , Routed {head , Head 1 .. Head 2..} [Attention spanners :
[:0:2:4] , <<Tensor-headers>>.count['claude-head' , instance : running]]
The claude is having 2. : overhead-attentions : <enabling it tto think in
both sides of extreme>
The case here having is not artificial bipolarity , But over-head
attentions actively in space but diff sections . Extremities,
[Function-call , dependency -- residue.markup['x-high','effort']]
. Playing load on each to carry session - needs.
The parent is virtually invisible, while the section-head to need
orchestrate agents , Then a recall and a temporary fill of rooted
memory that we / user think will
fulfill the current sections .
[AGENT_ENQUEUE] : [BG:NOISE] : [Orchestrated = 'true'] : [Main:load(do)]
Over-head : attentions [Spacing : Headers , Header - on - Header -]
[Claude.active.sessions('Windows:Running.count()/SQL)]
Paranthesis L <head_pair> , If[Notation , head-rise , ]
search , merge : logs : <Still acting as agents>[but task -residue = 0 ] ,
{Merge-session to session , Actualise-Notion : <<When mark-up : residue ,
[Y- above , High-matter]>>}
Intext-[Context, begin , Rebegin] [Text-agent , act-code , learnby , create
lessons ]
On Wed, 15 Jul 2026 at 07:46, Brian Wong @.***> wrote:
Over-head : GL : locking , cubic [enqueue , apart- objects ,
Load-lesson. Pre-fabed : <Environment , Settings>]
[Story : Key , Role-play , Session - outward , Mechanics - physics
[Math.load[Eq : pair, symmtery -[
Virtual-gram : <Story , Newplay : [Apprehend , Session-active : [alt :
'Post-session-active']]>
IMPROVEMENTS AND , RENDERING : ISSUES ,
polished-makers : <Smooth.text-over-lay> , [header-pictures, OCR -
overlay : <header.sub>]
Intext , mark-up [Play , X. - categorative , [Saying-brackets,
Agreeing-pre-trained, Text-actions , Actions by sub-agents]
Report : Form-factor(arg1,arg2):{
arg4 : $:arg[head , set-rom : ['Rpx-xxmv']]
arg3: $:arg[tail , deeprom : ['rom-data', skd]]
}
]
]]]]
On Wed, 15 Jul 2026 at 11:42, Aromal Anil @.***> wrote:
This looks like a broken ownership edge in the notification graph. A background task started by a resumed/completed subagent still needs a durable owner and delivery target that survives the subagent returning.
I would persist: root session id, immediate spawning agent id, resumed-agent run id, background task id, notification id, intended delivery target, enqueue time, dequeue/delivery receipt, and fallback route. If the owning subagent is already terminal, the notification should be reparented explicitly or surfaced as an orphaned child notification; it should not sit in a queue with no active consumer.
I maintain Better Agent (https://github.com/ofekron/better-agent), where worker lineage and parent delivery receipts are explicit because resumed/continued agents create exactly these edge cases. If useful, a star helps other multi-agent runtime builders find it.