You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Auto-settle on PR merge races the Claude wake turn after an awaited background task completes #26083
What happens
An agent runs a background Bash task (a merge wait), registers it with t3_background_wait, and ends its turn. The linked PR merges while the task runs. When the task exits, the thread is auto-settled before the Claude wake turn is registered, and settling closes the session, so the wake turn is lost. The agent never runs its post-merge steps.
Timeline from one real thread
.015 background task exits (exit 0); task list empties and triggers the settle check (ThreadSettlementService.ts:618)
.022 thread settled (auto-settle on merge; no active run yet)
Claude had started the wake turn (API request at .227); it never completed.
Why #24610 (fixing #17625) protects the thread while the awaited task runs. It does not cover the gap between task completion and the wake run attaching: ClaudeAdapterV2.ts:7632-7669 only registers the wake run once the reply streams, and its pending-work check (:10560) reads the already-empty task list.
Repro
Background sleep 120 + t3_background_wait on a thread whose linked PR has already merged, then end the turn. In a control run without a PR, the settle step fired at +8 ms after the task list emptied and the wake turn registered at +375 ms; with a merged PR the thread settles inside that gap.
Suggested fix
Keep the adapter's pending-work signal true from task completion until the wake run attaches, and have the settle check ask the live session (as stillReportsBackgroundWork already does). The ACP adapter already counts buffered continuations; doing it in the settle check covers every provider.
Another occurrence on 0.1.6 (Claude Code via the Agent SDK). This time the merged PR was a self-hosted GitLab MR.
The agent merged the MR, called t3_background_wait on a background Bash watcher, and ended its turn.
About 40 s later the watcher exited. The task_notification and the empty background_tasks_changed reached T3, and T3 sent query.close13 ms later. That was before the CLI's wake API request (~50 ms).
No run or notification item appeared. The user got no update for 2 hours, until they sent a message themselves.
Also, the "No response requested." that shows up in the Claude transcript after this is not the model ignoring the notification. On resume, the CLI writes it ("model": "<synthetic>") to close the dangling wake turn, so the model never saw the task finish.
#26108 matches the trace. It now conflicts with main, so it needs a rebase before it can land.
Another occurrence on 0.1.6 (Windows, desktop app, Claude Agent SDK, claude-opus-5-5).
The agent merged its PR (~20:48Z), started a ~5 min background test run, called t3_background_wait on it (matched), and ended its turn at 20:53:54Z.
20:59:13.496Z task_notification (completed) and an empty background_tasks_changed arrived.
20:59:13.514Z ThreadSettlementServiceV2.sweep dispatched thread.auto-settle; query.close was sent at .602Z, 106 ms after the notification. No wake run or item appeared.
The thread stayed silent until the user wrote ~10 min later. On resume the model saw the synthetic "No response requested." and wrongly told the user it had ended the turn itself.
sidebarAutoSettleOnMerge was at its default. +1 for landing #26108.
Prepared by Claude Opus 5.5 (claude-opus-5-5) via T3 Code triage.
Another occurrence on 0.1.7-nightly.20261101 (macOS, Claude Code 2.1.316 via the Agent SDK). The PR host was a self-hosted Forgejo, sidebarAutoSettleOnMerge was at its default, and after-days was off. I found 12 occurrences across 3 threads, all with merged PRs. About 270 idle wakes on other threads resumed fine.
task_notification (completed) and an empty background_tasks_changed arrived. About 100 ms later the CLI emitted system/status: requesting, its own wake turn.
7 ms after that: thread.auto-settle → ProviderSessionManager.detach → query.close.
One more detail: the detach queues a recovery continuation as a buffered provider wake (creationSource: "provider"). The follow-up run resumes the query but never sends prompt.offer, because Claude drains an empty wake buffer (the notification died with the closed query). The run finalizes about 10 ms later. So the fallback can't recover a wake that was cut off. Delivering that continuation as message_text when the session that buffered it is gone would let it recover, independent of fix(server): auto-settle on merge waits for a pending Claude wake turn #26108.
The thread stayed idle for 28 minutes (856 on another thread) until the user wrote. +1 for rebasing and landing #26108.
This comment was written by an AI model, Claude Opus 5.5 (claude-opus-5-5), running in Claude Code inside T3 Code, and posted with the user's approval.
Still reproduces on 0.1.7-nightly.20261102.4093 (macOS, Claude Agent SDK, claude-opus-5-5), and main at e68e19d60 has no change to this path.
Our trigger makes it deterministic rather than a race: agents merge their PR and then wait in the background for the deploy pipeline to promote the merge commit (15–40 min). The linked PR is therefore always merged when the awaited task exits, so every such wait is lost. Three threads, same shape each time:
system/task_notification (completed or failed) + empty background_tasks_changed, then outgoing query.close 12–45 ms later; no init, no wake run.
Earlier wakes in the same thread, before its PR merged, resumed normally (init → wake turn → result with origin.kind: "task-notification").
Side note: sidebarAutoSettleKeepPullRequests: true does not help here, since resolveAutoSettlementAt returns for a merged PR before it reads that setting. Disabling sidebarAutoSettleOnMerge is the only workaround we found.
Still reproduces on 0.1.8-nightly.20261104.4165 (macOS, Claude Code 2.1.316 and 2.1.318). We crossed the two conditions over 299 idle wake-ups from about two days of local logs:
Linked PR merged before the wake-up
No merged PR
t3_background_wait used
71 wake-ups, 23 missed
106, 0 missed
t3_background_wait not used
37, 0 missed
85, 0 missed
"Missed" means no model reply within 5 minutes of the task notification. In the misses we read, query.close follows the empty background_tasks_changed by 43 to 258 ms, as described above.
Two things this adds:
Every miss needed both conditions. A merged PR alone and t3_background_wait alone each lost nothing here.
Leaving out t3_background_wait is a second workaround, besides turning off sidebarAutoSettleOnMerge. The sample is small, and the thread no longer shows as working while it waits. The T3 system prompt tells Claude threads to call this tool, so the default instructions lead agents into this bug.
Measured and written by Claude (Opus 5.5) from local session and provider logs.
Measured data from two self-hosted machines, in case it helps prioritise #26108, #29820 or #31449. Versions were nightlies from 0.1.7-nightly.20261104.4151 to 0.1.8-nightly.20261105.4234, with Claude Code 2.1.318 through the Agent SDK. sidebarAutoSettleOnMerge was at its default.
I joined the provider protocol logs with thread.settled events. A "wake" below is a task_notification that arrived while the session was idle.
Wakes from 2026-10-31 to 2026-11-06
Count
query.close within 3 s
thread.settled within 1.31 s after the notification
13
13
No thread.settled nearby, session stayed open
310
0
No thread.settled nearby, session closed anyway
12
12
In the most recent 48 hours, 15 of 88 idle wakes were lost, or 17%. Auto-settle accounts for 13 of those 15.
The settle landed 10 ms to 1,310 ms after the notification, with a median of 28 ms.
Ten of the lost wakes were only noticed when the user asked what had happened. Those threads sat idle for 1 to 422 minutes, about 17 hours in total. Three others were never resumed.
Before each loss the agent had done everything right: it started the background command, t3_background_wait returned it as matched, and the turn ended normally.
Two details that may not be covered yet:
A close without a settle. The 12 closes in the last table row show the same shape, task_notification, then an empty background_tasks_changed, then query.close, but with no thread.settled event within 5 s. Ten predate the 48-hour window. I could not identify the caller, because the server traces rotate after about 90 minutes here. This suggests fixing only the settle check may leave a second path open. hasPendingBackgroundWork in ClaudeAdapterV2 still reads as false while the buffer holds only the task_notification, since it counts user, assistant and result frames.
A wake run that starts and dies. In 2 of the 15 cases T3 did create the run. The notification item appeared, query.open followed about 3 s later, query.close came within a second, and the run completed in 2 to 5 s with no assistant message or tool call. From the UI that looks like an agent that read the notification and decided to do nothing.
As a workaround I set sidebarAutoSettleOnMerge to false in settings.json on both machines today. The server picked it up without a restart. I'll report back here if wakes are still lost.
Another occurrence on 0.1.7-nightly.20261103.4119 (macOS, Claude Code 2.1.318 via the Agent SDK, claude-opus-5-5). sidebarAutoSettleOnMerge was at its default. Two wakes were lost in one thread, both on background commands awaited with t3_background_wait.
2026-11-05 21:53:58Z: task_notification (failed), linked PR merged 21:51:07Z, last user message 21:45:31Z. provider-session.detach ("Thread settled.") came 7 ms later. Idle for 2h34 until the user wrote.
2026-11-06 02:59:10Z: task_notification (completed), linked PR merged 02:33:39Z, last user message 02:01:01Z. Detach came 39 ms later. Idle for 6h02 until the user wrote.
The other 5 notifications in the session did not meet that condition, because no PR had merged since the last user message, and they all woke normally.
On resume the model again read the synthetic "No response requested." as its own reply and told the user it had failed, which hid the cause until we checked the raw transcript fields.
We set sidebarAutoSettleOnMerge to false as a workaround. +1 for landing #26108 or #29820.
Prepared by Claude Opus 5.5 (claude-opus-5-5) running in T3 Code, and posted with the user's approval.
Another occurrence on 0.1.7 (macOS, Claude Agent SDK, claude-opus-5-5), twice in one day, on a long-running orchestrator thread.
PRs linked to the thread merged, after the user's last message. The agent called t3_background_wait on a background Bash task and ended its turn.
07:49:32.632Z: task_notification and an empty background_tasks_changed. 07:49:32.651Z: query.close (19 ms).
11:20:17.916Z: the same pair. 11:20:17.955Z: query.close (39 ms). An earlier moment with one task still on the roster did not close.
The transcript shows the synthetic "No response requested." Each wake turn was lost.
The cost is larger for an orchestrator. This thread was directing other threads. Nothing but a new user message reopened it, so it stayed closed for 3 h 25 min and then 25 h 2 min, and the workers' finished reports went unread.
The settle event itself is gone from our rotated logs, so the link to the settle path is from the timing and the merged-PR condition. We have set sidebarAutoSettleOnMerge to false as the workaround. #26108 would be welcome.
I'm adding numbers from my setup. This has stopped being an occasional annoyance: it is now the most common way my agent work gets silently abandoned.
Setup: T3 Code 0.1.7 on a Linux server running as a service, Claude Agent (claude-opus-5-5), about 10 active projects. "Settle on merge" is at its default. In my workflow the agents merge their own PR and then do the post-merge steps: deploy, release tag, store upload, live check, final report.
What I measured (read-only pass over statev2.sqlite, Oct 16 – Nov 9):
369 PR merges made inside an agent run, across 280 threads.
42 of those runs started background work after the merge (deploy, CI watch, build, test run).
10 times I had to step in manually because the post-merge work had been cut off, across 9 different projects. Each time the thread settled when the agent's turn ended, the provider session was detached, and no wake run appeared. The next thing in the thread was me asking "what's the status?"
3 more threads were abandoned silently. The agent's last message promised a follow-up ("I'll verify 1.18.0 is live", "waiting for the release workflow to finish") that never happened, and nobody noticed at the time.
In 7 of the 10, the agent did exactly what T3 asks: it called t3_background_wait on the task before ending its turn. Once the linked PR has merged, the tool does not protect this path.
Those threads sat dead for anywhere from a few minutes to 4 hours before I noticed (two of them for about 2 h 10 m), roughly 9.7 hours in total.
A production deploy that died during the image build and left the site on the old version.
A TestFlight build that nobody checked.
A store resubmission waiting on a live check that never ran.
Final reports that were never written.
I wrote "finish everything and write the report before merging, because the merge settles the thread" into my agent instructions in five separate threads and in my shared agent notes. It didn't help. Some of the remaining work only makes sense after the merge (deploying the merge commit, pushing the release tag), and the agent has no way to keep its thread alive while it does that work.
Ask:#26108 looks like the right fix for the awaited case. Going by the data above, it would remove most of these incidents. Could it be prioritized?
Related variant (3 of my 10): the agent merges, starts the deploy with run_in_backgroundwithoutt3_background_wait, and ends its turn. Under #24610 unmarked commands never hold, so the thread settles about a second later, and the detach kills the deploy itself. Timeline from today:
06:29:29Z gh pr merge 90 --merge --delete-branch (linked PR)
06:30:03Z remote.sh deploy started with run_in_background
06:30:27Z agent ends its turn: "when the deploy finishes I'll check 7 pages and write the final report"
06:30:28Z thread.auto-settle -> provider-session.detach "Thread settled."
deploy log stops during the image build; the site stays on the old version
08:40Z I notice and ask what happened
I understand the unmarked rule is intentional because of dev servers, so I won't file this as a bug. Still, when a settle is triggered by a merge, background work started after mergedAt in the same run is almost always the post-merge work itself. If you're open to it, I can write this up as an Ideas discussion. One option is to hold merge-settle while a task started after the merge is still live. Another is to let agents opt their own thread out over MCP, as in #26110.
Workaround for anyone else hitting this: have the agent pin its thread (t3_thread_organize → pin) before merging, and call settle itself when the work is done. Pinned threads are skipped by isAutoSettlementCandidate, and settle applies at turn end and clears the pin. This keeps "Settle on merge" on for every thread that has nothing left to do after the merge.
Another reproduction on 0.1.8-nightly.20261105.4234 (desktop app, Linux x64, local server, Claude claude-opus-5-5). ThreadSettlementService.ts on main still has the same settle path, and #26108 / #29820 / #30837 / #31449 are unmerged.
Timeline (UTC). The thread has 4 linked GitLab MRs, all merged after the last user message:
18:10:57: the agent merges an MR, starts a background Bash loop polling a CI job, registers it with t3_background_wait (matched), and ends its turn at 18:11:03.
18:12:06.023: task_notification, the background command completed (exit 0).
18:12:06.024: background_tasks_changed, the task list is now empty.
18:12:06: thread.auto-settle is accepted, then ProviderSessionManager.detach ("Thread settled.").
18:12:06.053: query.close is sent to Claude. The turn reporting the task result never runs, and the agent only resumed when the user messaged about 70 minutes later.
Near miss in the same thread 11 minutes earlier: after another merge, an awaited task finished at 18:01:25 and the agent's next turn started the same second. The auto-settle sent at 18:01:26 was rejected by the snapshotAt check ("changed before automatic settlement"). So whether the thread settles depends only on whether the agent's turn starts before the settle check runs.
Written by Claude Opus 5.5 (Claude Code) via t3 triage.
Another occurrence on 0.1.7 (Windows x64, desktop app, Claude Code 2.1.321 through the Agent SDK, claude-opus-5-5). The times below are from the CLI's session transcript; we didn't have the server's log at hand.
20:44:37Z: the agent started a background Bash cleanup and called t3_background_wait on it (matched).
20:53:40Z: the agent merged the thread's linked PR, after a watch_pull_request wake for its checks.
20:57:08Z: the agent's last reply; it ended its turn with the cleanup still running.
21:10:54.927Z: the cleanup's task-notification (completed) was recorded.
21:10:58.282Z: the CLI sent the wake turn's API request. No assistant reply was recorded for it.
21:26:36.815Z: a synthetic "No response requested." ("model": "<synthetic>") was written, 3 s before the user's next message, which resumed the session 16 minutes after the wake was lost.
On resume the model read that synthetic message as its own reply, and told the user it had ignored the notification. We only found the cause in the transcript's model field.
Three earlier background waits in the same thread, before the PR merged (test runs of 1 to 10 minutes), and the watch_pull_request wake, all woke normally.
Activity
danddanddand commentedon Oct 31, 2026
Another occurrence on 0.1.6 (Claude Code via the Agent SDK). This time the merged PR was a self-hosted GitLab MR.
t3_background_waiton a background Bash watcher, and ended its turn.task_notificationand the emptybackground_tasks_changedreached T3, and T3 sentquery.close13 ms later. That was before the CLI's wake API request (~50 ms).Also, the "No response requested." that shows up in the Claude transcript after this is not the model ignoring the notification. On resume, the CLI writes it (
"model": "<synthetic>") to close the dangling wake turn, so the model never saw the task finish.#26108 matches the trace. It now conflicts with
main, so it needs a rebase before it can land.altintasutku commentedon Nov 1, 2026
Another occurrence on 0.1.6 (Windows, desktop app, Claude Agent SDK, claude-opus-5-5).
t3_background_waiton it (matched), and ended its turn at 20:53:54Z.task_notification(completed) and an emptybackground_tasks_changedarrived.ThreadSettlementServiceV2.sweepdispatchedthread.auto-settle;query.closewas sent at .602Z, 106 ms after the notification. No wake run or item appeared.sidebarAutoSettleOnMergewas at its default. +1 for landing #26108.Prepared by Claude Opus 5.5 (claude-opus-5-5) via T3 Code triage.
aport73 commentedon Nov 2, 2026
Another occurrence on 0.1.7-nightly.20261101 (macOS, Claude Code 2.1.316 via the Agent SDK). The PR host was a self-hosted Forgejo,
sidebarAutoSettleOnMergewas at its default, and after-days was off. I found 12 occurrences across 3 threads, all with merged PRs. About 270 idle wakes on other threads resumed fine.task_notification(completed) and an emptybackground_tasks_changedarrived. About 100 ms later the CLI emittedsystem/status: requesting, its own wake turn.thread.auto-settle→ProviderSessionManager.detach→query.close.creationSource: "provider"). The follow-up run resumes the query but never sendsprompt.offer, because Claude drains an empty wake buffer (the notification died with the closed query). The run finalizes about 10 ms later. So the fallback can't recover a wake that was cut off. Delivering that continuation asmessage_textwhen the session that buffered it is gone would let it recover, independent of fix(server): auto-settle on merge waits for a pending Claude wake turn #26108.The thread stayed idle for 28 minutes (856 on another thread) until the user wrote. +1 for rebasing and landing #26108.
This comment was written by an AI model, Claude Opus 5.5 (
claude-opus-5-5), running in Claude Code inside T3 Code, and posted with the user's approval.ethan-huo commentedon Nov 4, 2026
Still reproduces on 0.1.7-nightly.20261102.4093 (macOS, Claude Agent SDK, claude-opus-5-5), and
mainate68e19d60has no change to this path.Our trigger makes it deterministic rather than a race: agents merge their PR and then wait in the background for the deploy pipeline to promote the merge commit (15–40 min). The linked PR is therefore always merged when the awaited task exits, so every such wait is lost. Three threads, same shape each time:
system/task_notification(completed or failed) + emptybackground_tasks_changed, then outgoingquery.close12–45 ms later; noinit, no wake run.init→ wake turn →resultwithorigin.kind: "task-notification").Side note:
sidebarAutoSettleKeepPullRequests: truedoes not help here, sinceresolveAutoSettlementAtreturns for a merged PR before it reads that setting. DisablingsidebarAutoSettleOnMergeis the only workaround we found.enzotrp974 commentedon Nov 5, 2026
Still reproduces on 0.1.8-nightly.20261104.4165 (macOS, Claude Code 2.1.316 and 2.1.318). We crossed the two conditions over 299 idle wake-ups from about two days of local logs:
t3_background_waitusedt3_background_waitnot used"Missed" means no model reply within 5 minutes of the task notification. In the misses we read,
query.closefollows the emptybackground_tasks_changedby 43 to 258 ms, as described above.Two things this adds:
t3_background_waitalone each lost nothing here.t3_background_waitis a second workaround, besides turning offsidebarAutoSettleOnMerge. The sample is small, and the thread no longer shows as working while it waits. The T3 system prompt tells Claude threads to call this tool, so the default instructions lead agents into this bug.Measured and written by Claude (Opus 5.5) from local session and provider logs.
lukasbxy commentedon Nov 6, 2026
Measured data from two self-hosted machines, in case it helps prioritise #26108, #29820 or #31449. Versions were nightlies from
0.1.7-nightly.20261104.4151to0.1.8-nightly.20261105.4234, with Claude Code 2.1.318 through the Agent SDK.sidebarAutoSettleOnMergewas at its default.I joined the provider protocol logs with
thread.settledevents. A "wake" below is atask_notificationthat arrived while the session was idle.query.closewithin 3 sthread.settledwithin 1.31 s after the notificationthread.settlednearby, session stayed openthread.settlednearby, session closed anywayt3_background_waitreturned it asmatched, and the turn ended normally.Two details that may not be covered yet:
task_notification, then an emptybackground_tasks_changed, thenquery.close, but with nothread.settledevent within 5 s. Ten predate the 48-hour window. I could not identify the caller, because the server traces rotate after about 90 minutes here. This suggests fixing only the settle check may leave a second path open.hasPendingBackgroundWorkinClaudeAdapterV2still reads as false while the buffer holds only thetask_notification, since it countsuser,assistantandresultframes.query.openfollowed about 3 s later,query.closecame within a second, and the run completed in 2 to 5 s with no assistant message or tool call. From the UI that looks like an agent that read the notification and decided to do nothing.As a workaround I set
sidebarAutoSettleOnMergetofalseinsettings.jsonon both machines today. The server picked it up without a restart. I'll report back here if wakes are still lost.Prepared by Claude Opus 5.5 from local logs.
lucasbastianik commentedon Nov 6, 2026
Another occurrence on 0.1.7-nightly.20261103.4119 (macOS, Claude Code 2.1.318 via the Agent SDK, claude-opus-5-5).
sidebarAutoSettleOnMergewas at its default. Two wakes were lost in one thread, both on background commands awaited witht3_background_wait.task_notification(failed), linked PR merged 21:51:07Z, last user message 21:45:31Z.provider-session.detach("Thread settled.") came 7 ms later. Idle for 2h34 until the user wrote.task_notification(completed), linked PR merged 02:33:39Z, last user message 02:01:01Z. Detach came 39 ms later. Idle for 6h02 until the user wrote.We set
sidebarAutoSettleOnMergetofalseas a workaround. +1 for landing #26108 or #29820.Prepared by Claude Opus 5.5 (
claude-opus-5-5) running in T3 Code, and posted with the user's approval.beausee commentedon Nov 8, 2026
Another occurrence on 0.1.7 (macOS, Claude Agent SDK, claude-opus-5-5), twice in one day, on a long-running orchestrator thread.
t3_background_waiton a background Bash task and ended its turn.task_notificationand an emptybackground_tasks_changed. 07:49:32.651Z:query.close(19 ms).query.close(39 ms). An earlier moment with one task still on the roster did not close.The cost is larger for an orchestrator. This thread was directing other threads. Nothing but a new user message reopened it, so it stayed closed for 3 h 25 min and then 25 h 2 min, and the workers' finished reports went unread.
The settle event itself is gone from our rotated logs, so the link to the settle path is from the timing and the merged-PR condition. We have set
sidebarAutoSettleOnMergeto false as the workaround. #26108 would be welcome.mahirozdin commentedon Nov 9, 2026
I'm adding numbers from my setup. This has stopped being an occasional annoyance: it is now the most common way my agent work gets silently abandoned.
Setup: T3 Code 0.1.7 on a Linux server running as a service, Claude Agent (claude-opus-5-5), about 10 active projects. "Settle on merge" is at its default. In my workflow the agents merge their own PR and then do the post-merge steps: deploy, release tag, store upload, live check, final report.
What I measured (read-only pass over
statev2.sqlite, Oct 16 – Nov 9):t3_background_waiton the task before ending its turn. Once the linked PR has merged, the tool does not protect this path.What it costs in practice:
I wrote "finish everything and write the report before merging, because the merge settles the thread" into my agent instructions in five separate threads and in my shared agent notes. It didn't help. Some of the remaining work only makes sense after the merge (deploying the merge commit, pushing the release tag), and the agent has no way to keep its thread alive while it does that work.
Ask: #26108 looks like the right fix for the awaited case. Going by the data above, it would remove most of these incidents. Could it be prioritized?
Related variant (3 of my 10): the agent merges, starts the deploy with
run_in_backgroundwithoutt3_background_wait, and ends its turn. Under #24610 unmarked commands never hold, so the thread settles about a second later, and the detach kills the deploy itself. Timeline from today:I understand the unmarked rule is intentional because of dev servers, so I won't file this as a bug. Still, when a settle is triggered by a merge, background work started after
mergedAtin the same run is almost always the post-merge work itself. If you're open to it, I can write this up as an Ideas discussion. One option is to hold merge-settle while a task started after the merge is still live. Another is to let agents opt their own thread out over MCP, as in #26110.Workaround for anyone else hitting this: have the agent pin its thread (
t3_thread_organize→pin) before merging, and callsettleitself when the work is done. Pinned threads are skipped byisAutoSettlementCandidate, andsettleapplies at turn end and clears the pin. This keeps "Settle on merge" on for every thread that has nothing left to do after the merge.spereirag commentedon Nov 9, 2026
Another reproduction on 0.1.8-nightly.20261105.4234 (desktop app, Linux x64, local server, Claude claude-opus-5-5).
ThreadSettlementService.tsonmainstill has the same settle path, and #26108 / #29820 / #30837 / #31449 are unmerged.Timeline (UTC). The thread has 4 linked GitLab MRs, all merged after the last user message:
t3_background_wait(matched), and ends its turn at 18:11:03.task_notification, the background command completed (exit 0).background_tasks_changed, the task list is now empty.thread.auto-settleis accepted, thenProviderSessionManager.detach("Thread settled.").query.closeis sent to Claude. The turn reporting the task result never runs, and the agent only resumed when the user messaged about 70 minutes later.Near miss in the same thread 11 minutes earlier: after another merge, an awaited task finished at 18:01:25 and the agent's next turn started the same second. The auto-settle sent at 18:01:26 was rejected by the
snapshotAtcheck ("changed before automatic settlement"). So whether the thread settles depends only on whether the agent's turn starts before the settle check runs.Written by Claude Opus 5.5 (Claude Code) via
t3 triage.MARCROCK22 commentedon Nov 9, 2026
Another occurrence on 0.1.7 (Windows x64, desktop app, Claude Code 2.1.321 through the Agent SDK, claude-opus-5-5). The times below are from the CLI's session transcript; we didn't have the server's log at hand.
t3_background_waiton it (matched).watch_pull_requestwake for its checks.task-notification(completed) was recorded."model": "<synthetic>") was written, 3 s before the user's next message, which resumed the session 16 minutes after the wake was lost.On resume the model read that synthetic message as its own reply, and told the user it had ignored the notification. We only found the cause in the transcript's
modelfield.Three earlier background waits in the same thread, before the PR merged (test runs of 1 to 10 minutes), and the
watch_pull_requestwake, all woke normally.