Skip to content

fix: make removeClineFromStack() delegation-aware to prevent orphaned parent tasks#11302

Draft
roomote[bot] wants to merge 2 commits intomainfrom
fix/delegation-aware-removeClineFromStack
Draft

fix: make removeClineFromStack() delegation-aware to prevent orphaned parent tasks#11302
roomote[bot] wants to merge 2 commits intomainfrom
fix/delegation-aware-removeClineFromStack

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Feb 8, 2026

Related GitHub Issue

Closes: #11301

Description

This PR attempts to address Issue #11301 where parent tasks become orphaned in a delegated state when a child task is removed via removeClineFromStack().

Root cause: removeClineFromStack() is a pure pop-and-dispose operation with no delegation awareness. When a delegated child task is removed (via Clear Task, navigate to history, or start new task), the parent's HistoryItem remains stuck with status: "delegated" and a stale awaitingChildId.

Fix: Makes removeClineFromStack() the delegation-aware chokepoint. After popping and disposing the child task, it now:

  1. Captures parentTaskId and childTaskId before abort/dispose (since abortTask(true) is async and the task reference is cleared later)
  2. Looks up the parent's HistoryItem via getTaskWithId(parentTaskId)
  3. If the parent has status === "delegated" and awaitingChildId === childTaskId, updates parent metadata: status -> "active", awaitingChildId -> undefined
  4. Persists via updateTaskHistory()
  5. Wraps the parent lookup + update in try/catch so failures are non-fatal (logged but do not block the pop)

This is a lightweight metadata repair (~20 lines), not a full delegation return. The parent simply becomes resumable from the task history list. All three affected paths (and any future callers) go through removeClineFromStack(), so this single fix covers everything.

Test Procedure

  • Added 6 new tests in src/__tests__/removeClineFromStack-delegation.spec.ts:
    • Delegated child removal repairs parent metadata (delegated -> active, awaitingChildId cleared)
    • Non-delegated task removal does not trigger any parent metadata changes
    • Mismatched awaitingChildId does not trigger repair
    • Non-delegated parent status does not trigger repair
    • Errors during parent lookup are caught and logged without blocking the pop
    • Empty stack is handled gracefully
  • All existing delegation-related tests continue to pass (provider-delegation.spec.ts, history-resume-delegation.spec.ts, nested-delegation-resume.spec.ts, single-open-invariant.spec.ts)
  • ClineProvider.spec.ts (88 tests) continues to pass

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Documentation Impact: No documentation updates required.
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Documentation Updates

  • No documentation updates are required.

Additional Notes

Feedback and guidance are welcome.


Important

Enhance removeClineFromStack() in ClineProvider.ts to update parent task metadata when a delegated child is removed, preventing orphaned parent tasks.

  • Behavior:
    • removeClineFromStack() in ClineProvider.ts now updates parent task metadata when a delegated child is removed, changing status from delegated to active and clearing awaitingChildId.
    • Handles errors during parent metadata update without blocking task removal.
    • Skips metadata repair if skipDelegationRepair option is true.
  • Tests:
    • Added removeClineFromStack-delegation.spec.ts with tests for parent metadata repair, non-delegated task removal, mismatched awaitingChildId, non-delegated parent status, error handling, empty stack, and nested delegation transitions.
    • Ensures existing tests in provider-delegation.spec.ts, history-resume-delegation.spec.ts, and others continue to pass.

This description was created by Ellipsis for 241c0a2. You can customize this summary. It will automatically update as commits are pushed.

@roomote
Copy link
Contributor Author

roomote bot commented Feb 8, 2026

Rooviewer Clock   See task

Re-reviewed the incremental changes (45d756e). The previously flagged nested delegation issue is resolved via the skipDelegationRepair opt-out flag. The new Gemini empty-stream handling, reasoning effort validation, and recursive subtask tree UI changes are clean and well-tested. No new issues found.

  • Fix: parent metadata repair in removeClineFromStack() incorrectly fires during delegateParentAndOpenChild() in nested delegation (3+ levels), prematurely resetting the grandparent's delegated status to active
Previous reviews

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

… parent tasks

When a delegated child task is removed via removeClineFromStack() (e.g., Clear
Task, navigate to history, start new task), the parent task was left orphaned
in "delegated" status with a stale awaitingChildId. This made the parent
unresumable without manual history repair.

This fix captures parentTaskId and childTaskId before abort/dispose, then
repairs the parent metadata (status -> active, clear awaitingChildId) when
the popped task is a delegated child and awaitingChildId matches.

Parent lookup + updateTaskHistory are wrapped in try/catch so failures are
non-fatal (logged but do not block the pop).

Closes #11301
@hannesrudolph hannesrudolph force-pushed the fix/delegation-aware-removeClineFromStack branch from 241c0a2 to 45d756e Compare February 8, 2026 05:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Parent task orphaned after clearing/navigating away from delegated child task

2 participants