Skip to content

Conversation

catrielmuller
Copy link

@catrielmuller catrielmuller commented Sep 11, 2025

Hi RooTeam, Catriel from KiloCode

Related GitHub Issue

Closes: #2534
Closes: #6624
Related: #6625
Related: https://discordapp.com/channels/1349288496988160052/1414333923118284922
Related: Kilo-Org/kilocode#2379

Description

This PR fixes an issue with the orchestrator mode where loading a child task from task history wouldn't properly reconstruct the task stack, preventing the parent task from resuming execution after the child task finishes.

  • Implements task stack reconstruction for subtasks loaded from history
  • Ensures proper parent-child task relationships are maintained
  • Adds robust error handling and logging for task resumption

Test Procedure

  • Disable the all auto approved tools
  • Select Orchestrator Mode
  • Use this prompt:
run 3 subtasks in sequence. the only thing you should do in each one is run 1 different "sleep 1" commands and then finish the subtask.
  • Before execute the first sleep command, close the vscode or restart the debug mode
  • Load the sub task from the Task history
  • Resume the execution
  • After finish the subtask should go back to the parent one and continue the execution of the parent task

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: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Documentation Updates

Does this PR necessitate updates to user-facing documentation?

  • No documentation updates are required.
  • Yes, documentation updates are required. (Please describe what needs to be updated or link to a PR in the docs repository).

Additional Notes

Get in Touch

Discord: catrielmuller


Important

Fixes task stack reconstruction in orchestrator mode, ensuring parent-child relationships are maintained across reloads, with new methods and tests added.

  • Behavior:
    • Fixes task stack reconstruction for subtasks loaded from history in ClineProvider.ts.
    • Ensures parent-child task relationships are maintained across extension reloads.
    • Adds error handling and logging for task resumption.
  • Functions:
    • Adds reconstructTaskStack() and continueParentTask() in ClineProvider.ts.
    • Modifies showTaskWithId() to handle task stack reconstruction.
  • Tests:
    • Adds ClineProvider.stack-reconstruction.spec.ts to test task stack reconstruction and parent-child relationships.
    • Tests include scenarios for nested subtasks, circular references, and standalone tasks.

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

@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. bug Something isn't working labels Sep 11, 2025
Copy link

@roomote roomote bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution! I've reviewed the changes and the implementation correctly addresses the core issue of parent-child task relationships being lost on extension reloads. The comprehensive test coverage and error handling are excellent. I've left some suggestions inline to help improve the implementation.

}
}
// Start the continuation in the background to avoid blocking
continueExecution()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential race condition: The task continuation is started in the background without awaiting it. This could lead to race conditions if multiple operations happen quickly.

Suggested change
continueExecution()
// Start the continuation and await it to ensure proper synchronization
await continueExecution()

Alternatively, consider implementing a queue or synchronization mechanism to handle concurrent operations safely.

await addToHierarchy(parentHistoryItem)
} catch (error) {
this.log(
`[buildTaskHierarchy] Failed to load parent task ${historyItem.parentTaskId}: ${error instanceof Error ? error.message : String(error)}`,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing error recovery: When a parent task fails to load, the error is logged but the hierarchy continues building. This could result in an incomplete or broken task stack.

Consider either:

  1. Throwing an error to stop the reconstruction
  2. Implementing a fallback strategy (e.g., treating the current task as root)
  3. Returning a partial hierarchy with a warning to the user

@@ -572,7 +572,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {

// API Messages

private async getSavedApiConversationHistory(): Promise<ApiMessage[]> {
public async getSavedApiConversationHistory(): Promise<ApiMessage[]> {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Encapsulation concern: Making these methods public breaks encapsulation. If these are only needed for task reconstruction, consider:

  1. Creating a TaskReconstruction interface with these specific methods
  2. Using a friend/internal pattern (e.g., @internal JSDoc tag)
  3. Moving the reconstruction logic into the Task class itself

This would maintain better separation of concerns and prevent misuse of these methods.

const hierarchy: HistoryItem[] = []
const visited = new Set<string>()

// Recursive function to build hierarchy
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding timeout protection to prevent indefinite waiting. For example:

public async waitForSubtask(timeoutMs: number = 60000) {
  const timeout = setTimeout(() => {
    clearInterval(this.pauseInterval)
    this.pauseInterval = undefined
    throw new Error('Subtask timeout exceeded')
  }, timeoutMs)
  
  await new Promise<void>((resolve) => {
    this.pauseInterval = setInterval(() => {
      if (!this.isPaused) {
        clearTimeout(timeout)
        clearInterval(this.pauseInterval)
        this.pauseInterval = undefined
        resolve()
      }
    }, 1000)
  })
}

const addToHierarchy = async (historyItem: HistoryItem): Promise<void> => {
// Prevent infinite loops
if (visited.has(historyItem.id)) {
return
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The circular reference protection works but could be more explicit. Consider adding a warning log when a circular reference is detected:

if (visited.has(historyItem.id)) {
  this.log('[buildTaskHierarchy] Warning: Circular reference detected for task ' + historyItem.id)
  return
}

This would help with debugging task hierarchy issues in production.

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Sep 11, 2025
@daniel-lxs daniel-lxs moved this from Triage to PR [Needs Prelim Review] in Roo Code Roadmap Sep 11, 2025
@hannesrudolph hannesrudolph added PR - Needs Preliminary Review and removed Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. labels Sep 11, 2025
@hannesrudolph
Copy link
Collaborator

@catrielmuller
https://github.com/user-attachments/assets/50a4edca-85d3-4375-a32d-22a0a0d78eed

@daniel-lxs daniel-lxs moved this from PR [Needs Prelim Review] to PR [Changes Requested] in Roo Code Roadmap Sep 11, 2025
@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Sep 12, 2025
@catrielmuller
Copy link
Author

catrielmuller commented Sep 12, 2025

@catrielmuller https://github.com/user-attachments/assets/50a4edca-85d3-4375-a32d-22a0a0d78eed

@hannesrudolph hannesrudolph I made some changes to fix this inconsistency. Now should work as expected.

@hannesrudolph
Copy link
Collaborator

hannesrudolph commented Sep 12, 2025

@catrielmuller Thank you! Just tested again, the child task does not restore with the original mode.

Nested subtasks seem to also cause breaking behaviour.
Try this prompt

create a subtask in ask mode with "use new_task code mode with "use ask_followup_question with what is your name?""
and then close the workspace or reload the dev environment while the code mode level task is working.

@catrielmuller
Copy link
Author

@catrielmuller Thank you! Just tested again, the child task does not restore with the original mode.

Nested subtasks seem to also cause breaking behaviour. Try this prompt

create a subtask in ask mode with "use new_task code mode with "use ask_followup_question with what is your name?""
and then close the workspace or reload the dev environment while the code mode level task is working.

@hannesrudolph , I added the mode switch and logs to track down the actions of this component.

create a subtask in ask mode with "use new_task code mode with "use ask_followup_question with what is your name?""
parent-mode-switch.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working PR - Changes Requested size:XXL This PR changes 1000+ lines, ignoring generated files.
Projects
Status: PR [Changes Requested]
Development

Successfully merging this pull request may close these issues.

Parent-child task relationships lost on extension reload Subtask Execution Interruption and Recovery Failure in Boomerang Mode
2 participants