Repository navigation
Description
PR auto-settlement closes Claude before an awaited background task can resume its thread
Claude threads can lose a background task's completion turn when a linked PR has merged. The last awaited task finishes, T3 auto-settles the thread, and session cleanup closes the SDK query before Claude's notification turn starts a T3 run.
Observed on T3 Code Nightly 0.1.10-nightly.20261111.4529, Claude Agent SDK provider, Claude Code CLI 2.1.322, macOS.
Reproduce
- Enable automatic settlement on PR merge. Link an open PR to a Claude thread.
- Have Claude start a long Bash command with
run_in_background: true. - Have Claude call
t3_background_waitwithtaskIds: ["<task ID>"], then end its turn. - Merge the linked PR while the command is running.
- Let the command exit.
The merged PR is the extra condition that explains the intermittent failures. The same problem occurs when continuing agent work after the linked PR has merged.
Expected and actual
Expected: Claude processes the task notification, T3 records a continuation run, and the agent continues its remaining work.
Actual: T3 closes the query during the notification handoff. The thread never resumes. On a later user message, the reopened Claude transcript contains the synthetic assistant text No response requested.
Evidence
The provider emits system task_updated, system task_notification, then system background_tasks_changed with tasks: [].
One failing sequence on 2026-11-11 UTC:
05:40:08.266 task_notification completed; background_tasks_changed tasks: []
05:40:08.274 provider-session.detach created by server:auto-settle:...
detail: "Thread settled."
05:40:08.276 outgoing query.close; detach completed
The linked PR had merged at 03:30:48 UTC. The provider log is events.mcp-launch-97a081c5501999334140dd4ed03291e7f15645b5c908c193d62c625712c139ad.log.1, lines 4877-4880. A read-only query of orchestration_v2_effect_outbox confirms the detach's command and reason.
In the initial log sample, 15 of 85 drains of waited tasks closed the query. The other 70 stayed open. All 59 drains of tasks never passed to t3_background_wait stayed open. All 15 immediate closes match a server:auto-settle:... detach with detail: "Thread settled." in the effect outbox. All five affected threads had a linked PR that had already merged.
In successful cases, the query stays open and system init follows the drain about 20-70 ms later. T3 then starts the notification run. Time since the previous result and earlier query reopenings do not separate the cases. The CLI-side trace shows it had already dequeued the notification and sent an API request in a failing case.
Code path
Read on main at 00766e2c027ac095e604da81b958113287f2f6b1:
t3_background_waitmarks roster task IDs awaited.- The idle notification is buffered before its task is removed. The continuation waits for a root wake frame, so the notification alone does not protect the thread with a run.
- An empty provider roster schedules a settlement sweep. The candidate guard checks active runs and awaited work, and the merged PR makes it eligible immediately.
- Settlement detaches the provider session. The Claude session finalizer closes the live query.
Suggested fix
Keep an explicit pending-wake blocker when an awaited task notification arrives. Preserve it through the empty roster until the continuation starts and settles, or the adapter confirms that no wake remains. Automatic settlement must honor that blocker before detaching the session. Treating the notification as the start of a run is another option, provided it handles absorbed and duplicate notifications.
A regression case should merge the linked PR while the root turn has ended, emit the notification and empty roster, delay system init, and assert that T3 keeps the query open and records the continuation.
Related investigation: https://github.com/birbprophet/agent-kit/issues/367.
Activity
juliusmarminge commentedon Nov 11, 2026
This is the same problem as #26083, so I'm closing it in favour of that one. If it is different, say how and it will be reopened.