Summary
Opening a second VS Code window while a subtask is running in another window silently corrupts the delegation link between the parent task and that subtask. The new window's TaskHistoryStore startup reconciliation treats the running child as a crash orphan and rewrites both records: child active → interrupted, parent delegated → active with awaitingChildId cleared. When the subtask later calls attempt_completion, its delegation guard (parentHistory.awaitingChildId === task.taskId in src/core/tools/AttemptCompletionTool.ts) fails against the mangled history and takes the "parent already detached" path. The subtask shows as completed, and the parent never resumes.
Reproduction
- In one VS Code window, run a task that delegates a subtask (parent
delegated, child active).
- While the subtask is running, open a second VS Code window. Both windows share the extension's single
globalStorage/tasks directory.
- Let the subtask reach
attempt_completion and approve finishing the subtask.
Expected: the parent resumes with the subtask's result.
Observed: the subtask completes; the parent never resumes.
The trigger is the new window's startup, not user activity — a hands-free session only escapes it because it rarely coincides with a window launch.
Consequences
- The subtask's result never reaches the parent and the parent's continuation never runs; to the user the parent silently stops while the subtask shows completed.
- The persisted history contradicts reality (parent not awaiting, child
interrupted, both tasks in fact live), which misroutes follow-up operations: ClineProvider.reopenParentFromDelegation() aborts with "parent is no longer delegated to child", and the child survives only as a history-replay resume whose parent link is already gone.
- Every window start that coincides with an in-flight delegation applies this rewrite — the repair's crash assumption is false for all live peers sharing the task store.
Root cause
TaskHistoryStore.initialize() runs reconcileDelegationState(), whose repair case "parent delegated, child active → child interrupted, parent active" rests on the stated assumption that "an active child persisted across startup cannot have a live task session behind it" (repairActiveDelegation()). With one extension host that is sound; with several VS Code windows sharing one task store it is not — window B's recovery pass mutates window A's running tasks.
Where to look
src/core/task-persistence/TaskHistoryStore.ts — initialize(), reconcileDelegationState() / reconcileDelegationStateCore(), repairActiveDelegation()
src/core/tools/AttemptCompletionTool.ts — the awaitingChildId delegation guard
src/core/webview/ClineProvider.ts — reopenParentFromDelegation()'s stale-parent guard
Observed on a main build (v3.86.0, 2026-10-04).
Summary
Opening a second VS Code window while a subtask is running in another window silently corrupts the delegation link between the parent task and that subtask. The new window's
TaskHistoryStorestartup reconciliation treats the running child as a crash orphan and rewrites both records: childactive → interrupted, parentdelegated → activewithawaitingChildIdcleared. When the subtask later callsattempt_completion, its delegation guard (parentHistory.awaitingChildId === task.taskIdinsrc/core/tools/AttemptCompletionTool.ts) fails against the mangled history and takes the "parent already detached" path. The subtask shows as completed, and the parent never resumes.Reproduction
delegated, childactive).globalStorage/tasksdirectory.attempt_completionand approve finishing the subtask.Expected: the parent resumes with the subtask's result.
Observed: the subtask completes; the parent never resumes.
The trigger is the new window's startup, not user activity — a hands-free session only escapes it because it rarely coincides with a window launch.
Consequences
interrupted, both tasks in fact live), which misroutes follow-up operations:ClineProvider.reopenParentFromDelegation()aborts with "parent is no longer delegated to child", and the child survives only as a history-replay resume whose parent link is already gone.Root cause
TaskHistoryStore.initialize()runsreconcileDelegationState(), whose repair case "parentdelegated, childactive→ childinterrupted, parentactive" rests on the stated assumption that "an active child persisted across startup cannot have a live task session behind it" (repairActiveDelegation()). With one extension host that is sound; with several VS Code windows sharing one task store it is not — window B's recovery pass mutates window A's running tasks.Where to look
src/core/task-persistence/TaskHistoryStore.ts—initialize(),reconcileDelegationState()/reconcileDelegationStateCore(),repairActiveDelegation()src/core/tools/AttemptCompletionTool.ts— theawaitingChildIddelegation guardsrc/core/webview/ClineProvider.ts—reopenParentFromDelegation()'s stale-parent guardObserved on a
mainbuild (v3.86.0, 2026-10-04).