diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 6f6f2d684a..42417637cb 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -758,6 +758,14 @@ export class Task extends EventEmitter { // this is the result of what it has done add the message to the chat // history and to the webview ui. try { + // Check if the task is aborted or abandoned before trying to add messages + if (this.abort || this.abandoned) { + this.providerRef + .deref() + ?.log(`[subtasks] Parent task ${this.taskId} is aborted/abandoned, skipping resume message`) + return + } + await this.say("subtask_result", lastMessage) await this.addToApiConversationHistory({ @@ -769,7 +777,8 @@ export class Task extends EventEmitter { .deref() ?.log(`Error failed to add reply from subtask into conversation of parent task, error: ${error}`) - throw error + // Don't throw the error - we still want the parent task to be unpaused + // even if we couldn't add the message } } diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index 720e5cda0d..596c34fa4e 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -204,7 +204,21 @@ export const webviewMessageHandler = async ( // Check if the current task actually has a parent task const currentTask = provider.getCurrentCline() if (currentTask && currentTask.parentTask) { - await provider.finishSubTask(t("common:tasks.canceled")) + // For subtasks, we need to ensure the parent task is resumed even if the subtask is in an error state + try { + // First abort the current subtask if it's still running + if (currentTask.isStreaming || !currentTask.didFinishAbortingStream) { + currentTask.abortTask() + // Small delay to ensure abort signal is processed before cleanup + // This prevents race conditions where the stream might still be processing + await new Promise((resolve) => setTimeout(resolve, 100)) + } + await provider.finishSubTask(t("common:tasks.canceled")) + } catch (error) { + // If there's an error, still try to resume the parent task + provider.log(`Error during subtask cancellation: ${error}`) + await provider.finishSubTask(t("common:tasks.canceled")) + } } else { // Regular task - just clear it await provider.clearTask()