File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -3552,7 +3552,11 @@ export class ClineProvider
35523552 } `,
35533553 )
35543554 try {
3555- await this . removeClineFromStack ( { skipDelegationRepair : true } )
3555+ // Only pop the stack if the child we just created is still on top.
3556+ // A concurrent delegation could have pushed another child since we created ours.
3557+ if ( this . getCurrentTask ( ) ?. taskId === child . taskId ) {
3558+ await this . removeClineFromStack ( { skipDelegationRepair : true } )
3559+ }
35563560 } catch ( cleanupError ) {
35573561 this . log (
35583562 `[delegateParentAndOpenChild] Failed to close paused child ${ child . taskId } during rollback: ${
@@ -3757,6 +3761,9 @@ export class ClineProvider
37573761
37583762 // 3) Persist parent metadata before closing the child. If persistence fails,
37593763 // the delegated child remains active and can retry completion.
3764+ // NOTE: steps 3 and 5 are still two separate writes — this is a known gap
3765+ // (reviewed finding #3). Story 2.2 (#365) will replace them with a single
3766+ // atomicUpdatePair() call so no intermediate state is ever persisted.
37603767 const childIds = Array . from ( new Set ( [ ...( historyItem . childIds ?? [ ] ) , childTaskId ] ) )
37613768 if ( historyItem . status !== "active" ) {
37623769 assertValidTransition ( historyItem . status , "active" )
You can’t perform that action at this time.
0 commit comments