Repository navigation
[Bug]: Claude background subagent completion is overwritten by a late 'running' update, and Stop/cancel can't settle it #22279
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Related, but with a different trigger or not covering the dismiss gap: #17099 (wake continuation runs on another provider), #18910 (stays Running after task_notification reports completed), #19993 (parent subagent hits a usage limit), #20430 (continuation gate jam).
Area
apps/server
Steps to reproduce
- On a Claude thread running on provider instance A (
claudeAgent_me), have the agent start background subagents (Agentwithrun_in_background). - While they are running, the instance hits its usage limit. Move the thread in place to another Claude instance B (
claudeAgent_wrenraeconner) witht3_thread_configure, and continue the thread there. Same driver, different account. - Let the subagents finish.
- Try to clear the rows that stay Running.
Expected behavior
- When their work ends, the subagents reach a terminal state, even if the parent thread has moved to another instance of the same driver.
- If T3 loses the completion anyway, there is a supported way to settle the row (Stop, dismiss, or
task_cancel), without restarting the server or editing the database.
Actual behavior
Two provider-native subagents have shown Running in the Lineage panel for more than 62 hours, and their timers are still counting. Both did their work and returned on 2026-10-17. Nothing on the machine belongs to them.
orchestration_v2_projection_subagents rows (redacted):
node:provider:claudeAgent:native-item:task%3Aade21fe3f39a4fcdc | run ordinal 650 | origin provider_native | instance claudeAgent_me | status running | started 2026-10-17T18:38:25.906Z | completed_at NULL | updated_at 2026-10-20T10:38:12Z
node:provider:claudeAgent:native-item:task%3Aae896c94795fd8e2d | run ordinal 668 | origin provider_native | instance claudeAgent_me | status running | started 2026-10-17T19:56:52.782Z | completed_at NULL | updated_at 2026-10-20T10:38:09Z
Timeline (UTC, 2026-10-17):
- Runs 650 and 668 start the subagents on
claudeAgent_me. - Run 675, at 21:25, is the first on
claudeAgent_wrenraeconner, after the limit move. The thread later moved again, to a third Claude instance. - One subagent's last activity was about 19:35, before the move; the other's was about 22:17, after it.
- Both rows still read
running.updated_atkeeps advancing, so something touches them without settling them.
Nothing user-facing clears them:
- Stop on the thread, and settling, do nothing.
- MCP
task_cancelon either id returnstask_not_found: "Delegated task node:provider:claudeAgent:native-item:task%3Aade21fe3f39a4fcdc does not belong to thread 35fd672a-…". It only accepts app-owned delegated tasks. - MCP
t3_workflow_stopwith the subagent id returnsinvalid_request: "This workflow is no longer running." So the server knows nothing is running, but the projection still says running. TaskStop/SendMessagefrom the current Claude session can't reach them, because they belonged to the earlier session and instance.
Impact
Minor bug or occasional failure
Version or commit
0.0.46-nightly.20261013.3042 (Arch t3code-nightly-bin)
Environment
Arch Linux (kernel 7.0.12), desktop app. Claude Agent SDK provider with several Claude account instances (claudeAgent_*). Parent claude-opus-5-5; subagents claude-fable-5-1 and claude-opus-5-5.
Workaround
None supported. #17099 reports that server-restart recovery (ProviderRuntimeRecoveryService) cancels such rows. A restart interrupts every other running agent, though, so it isn't usable mid-work.
Suggestion: when t3_workflow_stop or Stop finds a provider-native subagent that is "no longer running", settle its row instead of refusing. Or let task_cancel accept provider-native subagent ids.
Activity
[-][Bug]: Claude background subagents stay Running forever after the thread moves to another Claude instance, and nothing can settle them[/-][+][Bug]: Claude background subagent completion is overwritten by a late 'running' update, and Stop/cancel can't settle it[/+]shaneconner commentedon Oct 20, 2026
Update: root cause found. The instance move in the title was not the cause. I read the event log and the source at
5d6e4192(the commit this nightly was built from). Both subagents did complete on time, and a laterunningupdate from the same session overwrote each completion seconds later. Both completions happened before the thread moved instances at 21:25.Event log (
orchestration_events,subagent.updatedfor each node):task%3Aade21fe3f39a4fcdctask%3Aae896c94795fd8e2dThere is no
node.updatedor newtask_startedbetween them, so these aren't resumes. It looks like a stale in-flight progress update landing after the completion.Why it sticks:
subagent.updatedwithout checking state:apps/server/src/orchestration-v2/ProjectionStore.ts:2058(the UPSERT). A terminal row can go back torunning.ClaudeAdapterV2.ts:4863-4870, 5024-5038), so they don't protect the persisted row.subagent.stopre-emits the record with onlyupdatedAtbumped (Orchestrator.ts:9019-9031). That's why Stop "succeeds" and keeps advancingupdated_atwhile the row staysrunning.ProviderRuntimeRecoveryService.ts:470-483).Suggested fixes:
subagent.updatedreplace a terminal row in the projector, and do the same check in the adapter before emitting.subagent.stopsettle the row when the provider reports the task is no longer running, rather than only bumpingupdatedAt.I settled our two rows by appending
subagent.updatedandturn-item.updatedevents in the server's own shape, with the matching projection rows, in one transaction. That held without a restart, and a replay on a copy reproduced the same rows.