@@ -933,6 +933,8 @@ export class ClineProvider
933933 onCreated : this . taskCreationCallback ,
934934 startTask : options ?. startTask ?? true ,
935935 enableBridge : BridgeOrchestrator . isEnabled ( cloudUserInfo , taskSyncEnabled ) ,
936+ // Preserve the status from the history item to avoid overwriting it when the task saves messages
937+ initialStatus : historyItem . status ,
936938 } )
937939
938940 if ( isRehydratingCurrentTask ) {
@@ -3017,9 +3019,15 @@ export class ClineProvider
30173019 }
30183020
30193021 // 4) Create child as sole active (parent reference preserved for lineage)
3020- const child = await this . createTask ( message , undefined , parent as any , { initialTodos } )
3022+ // Pass initialStatus: "active" to ensure the child task's historyItem is created
3023+ // with status from the start, avoiding race conditions where the task might
3024+ // call attempt_completion before status is persisted separately.
3025+ const child = await this . createTask ( message , undefined , parent as any , {
3026+ initialTodos,
3027+ initialStatus : "active" ,
3028+ } )
30213029
3022- // 4 ) Persist parent delegation metadata
3030+ // 5 ) Persist parent delegation metadata
30233031 try {
30243032 const { historyItem } = await this . getTaskWithId ( parentTaskId )
30253033 const childIds = Array . from ( new Set ( [ ...( historyItem . childIds ?? [ ] ) , child . taskId ] ) )
@@ -3039,7 +3047,7 @@ export class ClineProvider
30393047 )
30403048 }
30413049
3042- // 5 ) Emit TaskDelegated (provider-level)
3050+ // 6 ) Emit TaskDelegated (provider-level)
30433051 try {
30443052 this . emit ( RooCodeEventName . TaskDelegated , parentTaskId , child . taskId )
30453053 } catch {
@@ -3164,7 +3172,22 @@ export class ClineProvider
31643172
31653173 await saveApiMessages ( { messages : parentApiMessages as any , taskId : parentTaskId , globalStoragePath } )
31663174
3167- // 3) Update parent metadata and persist BEFORE emitting completion event
3175+ // 3) Update child metadata to "completed" status
3176+ try {
3177+ const { historyItem : childHistory } = await this . getTaskWithId ( childTaskId )
3178+ await this . updateTaskHistory ( {
3179+ ...childHistory ,
3180+ status : "completed" ,
3181+ } )
3182+ } catch ( err ) {
3183+ this . log (
3184+ `[reopenParentFromDelegation] Failed to persist child completed status for ${ childTaskId } : ${
3185+ ( err as Error ) ?. message ?? String ( err )
3186+ } `,
3187+ )
3188+ }
3189+
3190+ // 4) Update parent metadata and persist BEFORE emitting completion event
31683191 const childIds = Array . from ( new Set ( [ ...( historyItem . childIds ?? [ ] ) , childTaskId ] ) )
31693192 const updatedHistory : typeof historyItem = {
31703193 ...historyItem ,
@@ -3176,35 +3199,24 @@ export class ClineProvider
31763199 }
31773200 await this . updateTaskHistory ( updatedHistory )
31783201
3179- // 4 ) Emit TaskDelegationCompleted (provider-level)
3202+ // 5 ) Emit TaskDelegationCompleted (provider-level)
31803203 try {
31813204 this . emit ( RooCodeEventName . TaskDelegationCompleted , parentTaskId , childTaskId , completionResultSummary )
31823205 } catch {
31833206 // non-fatal
31843207 }
31853208
3186- // 5 ) Close child instance if still open (single-open-task invariant)
3209+ // 6 ) Close child instance if still open (single-open-task invariant)
31873210 const current = this . getCurrentTask ( )
31883211 if ( current ?. taskId === childTaskId ) {
31893212 await this . removeClineFromStack ( )
31903213 }
31913214
3192- // 5b) Mark child subtask as "completed" to prevent duplicate tool_result on revisit
3193- try {
3194- const { historyItem : childHistory } = await this . getTaskWithId ( childTaskId )
3195- await this . updateTaskHistory ( {
3196- ...childHistory ,
3197- status : "completed" ,
3198- } )
3199- } catch {
3200- // non-fatal: child history may not exist for some edge cases
3201- }
3202-
3203- // 6) Reopen the parent from history as the sole active task (restores saved mode)
3215+ // 7) Reopen the parent from history as the sole active task (restores saved mode)
32043216 // IMPORTANT: startTask=false to suppress resume-from-history ask scheduling
32053217 const parentInstance = await this . createTaskWithHistoryItem ( updatedHistory , { startTask : false } )
32063218
3207- // 7 ) Inject restored histories into the in-memory instance before resuming
3219+ // 8 ) Inject restored histories into the in-memory instance before resuming
32083220 if ( parentInstance ) {
32093221 try {
32103222 await parentInstance . overwriteClineMessages ( parentClineMessages )
@@ -3221,7 +3233,7 @@ export class ClineProvider
32213233 await parentInstance . resumeAfterDelegation ( )
32223234 }
32233235
3224- // 8 ) Emit TaskDelegationResumed (provider-level)
3236+ // 9 ) Emit TaskDelegationResumed (provider-level)
32253237 try {
32263238 this . emit ( RooCodeEventName . TaskDelegationResumed , parentTaskId , childTaskId )
32273239 } catch {
0 commit comments