[Bug]: Cancelling a queued Claude continuation run leaves `requestedContinuations` set, so every later wake on that thread is dropped#30052
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/desktop
Steps to reproduce
- On a Claude thread, have the agent start a background task (a
run_in_backgroundBash command or a backgroundAgent) and end its turn. - Make the task finish while the thread still has an active run, for example while a run from a user message is still running or finalizing. Claude starts a wake turn, T3 offers a continuation, and the continuation run lands in the thread's queue as
queued. - Cancel that queued continuation run before it starts. Use the queue UI or the MCP
t3_queuetool withaction: "cancel". - Once the thread is idle, have the agent start another background task and end its turn.
- Let that task finish.
Expected behavior
A continuation run that ends without starting releases the wake latch for its native thread. This covers cancel and, by the same path, promote_to_steer. The wake in step 5 then opens a run, and its output shows in the thread.
Actual behavior
The wake in step 5 gets no run. The Claude CLI wakes and works anyway, but T3 does not own that turn:
- None of its messages reach the thread, including the final report.
- The thread shows Completed while the agent is still working.
- Any T3 MCP tool called in that turn, such as
t3_background_waitort3_thread_send, fails with{"code":"parent_not_active","message":"The calling provider no longer owns an active thread run."}.
Every later wake on that native thread is dropped the same way until the query is reopened or the runtime restarts. User turns do not clear it.
From reading the bundled server code: bufferWakeMessage returns early when requestedContinuations already holds the native thread. That set is cleared in only two places:
- in the continuation start path, right after
attachTurn; - in
clearWakeStateForNativeThread, which runs only on query reopen, a native-thread switch, or a runtime restart.
A queued continuation that is cancelled never reaches attachTurn, so its entry stays set. The same applies to one promoted with promote_to_steer, since its message moves into another run. I saw the cancel case live twice. The promote_to_steer case comes from reading the code only.
This is the same latch as #28163, which covers a failed wake dispatch. The trigger here is different and deterministic: it is a normal user or agent action, and the fix point is different too, since the cancel and promote paths would release the latch. It is related to #20430.
Impact
Major degradation or frequent failure
Version or commit
0.1.7-nightly.20261103.4106
Environment
macOS 26.5.1, desktop app, claudeAgent with claude-opus-5-5.
Logs or stack traces
| 1 | Two incidents on 2026-11-03 (UTC), from `statev2.sqlite` and the provider event logs, on two different threads: |
| 2 | |
| 3 | | Thread | Continuation run (`userMessageId` `message:thread:…`) | Cancelled before start | Next wake | |
| 4 | |---|---|---|---| |
| 5 | | A | requested 08:00:59 while run 12 was active | 08:02:00 (`t3_queue` cancel) | 08:08:13: background subagent ends, Claude wakes at 08:08:17, no continuation offered (`server.trace` has none for this thread after 08:00:59, while other threads got offers at 08:08:19 and 08:08:37). `t3_background_wait` failed 3 times with `parent_not_active` at 08:08:36, 08:08:52 and 08:09:12. | |
| 6 | | B | requested 08:47:34 while run 33 was finishing | 08:47:57 (`t3_queue` cancel) | 09:06:59: wake turn runs with no T3 run | |
Screenshots, recordings, or supporting files
No response
Workaround
Avoid cancelling or promoting a queued continuation run; let it run. Reopening the provider query (or restarting the runtime) clears the latch.