fix(executor): subflow edge keys mismatch#4202
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryMedium Risk Overview Adds targeted regression tests around loop sentinel start/end readiness and internal-vs-external edge reset behavior, and refactors loop/parallel orchestrators to emit a new Reviewed by Cursor Bugbot for commit 5e143b6. Configure here. |
Greptile SummaryThis PR fixes a stall bug where consecutive loops — an empty one followed by a populated one — would cause the second loop to hang after its first iteration. The root cause was Confidence Score: 5/5Safe to merge — the one-line edge-key fix is well-reasoned, backed by three targeted regression tests, and the remaining finding is a P2 style cleanup. All substantive findings are P2 or lower (unused return type). The core bug fix is correct, well-documented, and fully tested. The utility refactor cleanly deduplicates loop/parallel completion logic without changing observable behavior. apps/sim/executor/utils/subflow-utils.ts — minor unused Promise return type in emitSubflowSuccessEvents Important Files Changed
Sequence DiagramsequenceDiagram
participant External as External Node
participant SentinelStart as Loop Sentinel-Start
participant Body as Loop Body
participant SentinelEnd as Loop Sentinel-End
participant EdgeMgr as EdgeManager
Note over External,EdgeMgr: Empty upstream loop cascades deactivation
External->>EdgeMgr: processOutgoingEdges({selectedOption: 'else'})
EdgeMgr->>EdgeMgr: deactivateEdgeAndDescendants(external-node, sentinel-start)
Note over EdgeMgr: deactivatedEdges = {external-node-sentinel-start-...}
Note over External,EdgeMgr: Populated loop resets for next iteration
EdgeMgr->>EdgeMgr: clearDeactivatedEdgesForNodes({sentinel-start, body, sentinel-end})
Note over EdgeMgr: OLD: includes(-sentinel-start-) also matched<br/>external-node-sentinel-start-... → wrongly cleared!
Note over EdgeMgr: NEW: startsWith(sentinel-start-) only matches<br/>edges where sentinel-start is SOURCE → external edge preserved
SentinelEnd->>EdgeMgr: processOutgoingEdges({selectedRoute: loop_continue})
EdgeMgr->>SentinelStart: incomingEdges: only loop_continue active
Note over SentinelStart: countActiveIncomingEdges = 0 → READY ✓
Reviews (1): Last reviewed commit: "fix(executor): subflow edge keys mismatc..." | Re-trigger Greptile |
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 5e143b6. Configure here.
Summary
Test this workflow. Consecutive loops case with empty followed by populated breaks due to edge key mismatch.
Manual trigger
↓
[Seed] (Function)
return { empty: [], populated: [1, 2, 3] }
↓
[LoopEmpty] forEach <seed.result.empty>
└─ body: Function return <loop.currentItem>
↓ (loop-end-source → loop container)
[LoopWork] forEach <seed.result.populated>
└─ body: Function return <loop.currentItem>
Type of Change
Testing
Tested pre and post fix. Added unit tests.
Checklist