Skip to content

fix(parallel): remove broken node-counting completion in parallel blocks#4045

Open
waleedlatif1 wants to merge 1 commit intostagingfrom
waleedlatif1/parallel-error-handling
Open

fix(parallel): remove broken node-counting completion in parallel blocks#4045
waleedlatif1 wants to merge 1 commit intostagingfrom
waleedlatif1/parallel-error-handling

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

Summary

  • Parallel blocks used totalExpectedNodes = branchCount * allNodesInParallel to detect completion, which is wrong when branches have conditional paths (error edges, conditions)
  • Success branches complete fewer nodes than error branches, so the count never matches and the counting-based aggregation misfires
  • Removed the counting mechanism entirely — sentinel-end (triggered by edge processing) is the correct and sole mechanism for detecting parallel completion

Type of Change

  • Bug fix

Testing

All 662 executor tests pass. Tested with parallel blocks containing error edges.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Apr 8, 2026 7:46am

Request Review

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 8, 2026

PR Summary

Medium Risk
Changes parallel execution completion/aggregation behavior in the executor, which can affect when/if parallel results are produced for real workflows; scope is contained to parallel orchestration and covered by existing tests.

Overview
Fixes parallel block completion by removing the node-counting based “all branches complete” detection that broke when branches follow conditional/error paths.

ParallelScope/ExecutionContext.parallelExecutions drop completedCount/totalExpectedNodes, initializeParallelScope no longer accepts a terminal-node count, and handleParallelBranchCompletion now only records per-branch outputs while aggregation is performed solely by the parallel sentinel-end path. Tests were updated to match the new initializer signature and scope shape.

Reviewed by Cursor Bugbot for commit 8c7b975. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 8, 2026

Greptile Summary

This PR removes a broken node-counting completion mechanism from parallel block execution. Previously, parallel completion was detected by counting node executions against totalExpectedNodes = branchCount * allNodesInParallel, which failed whenever branches took conditional paths (error edges, condition gates) — since each branch could execute a different number of nodes, the counter never matched and aggregation could misfire or never fire. The fix removes completedCount and totalExpectedNodes entirely from ParallelScope and delegates completion detection solely to the sentinel-end node, which is only reached once all branches have exited via the DAG edge mechanism.

Key changes:

  • Removed completedCount / totalExpectedNodes from ParallelScope (state.ts), ExecutionContext.parallelExecutions inline type (types.ts), all test fixtures, and the orchestrator logic (parallel.ts)
  • handleParallelBranchCompletion now returns void instead of boolean — its sole job is to record the branch output
  • All call sites in node.ts that previously checked the boolean return value and called aggregateParallelResults on true are updated; aggregation is now exclusively triggered inside handleParallelSentinel when sentinelType === 'end'
  • initializeParallelScope signature simplified (removed terminalNodesCount parameter)
  • Test fixtures updated to drop the two removed fields

Confidence Score: 5/5

Safe to merge — the fix is correct, the cleanup is thorough, and all 662 existing tests pass.

The broken counting mechanism is fully excised and the sentinel-end trigger is the right and only completion signal. All callers in node.ts are updated, the interface types are consistent, and the test fixtures are cleaned up. The only remaining item is a P2 suggestion for an explicit regression test for the conditional-path scenario, which does not block merge.

apps/sim/executor/orchestrators/parallel.test.ts — could benefit from a regression test for the conditional-path bug scenario described in the PR.

Vulnerabilities

No security concerns identified. The changes are purely internal execution-engine refactoring with no user-input handling, authentication, or data-exposure surface.

Important Files Changed

Filename Overview
apps/sim/executor/orchestrators/parallel.ts Core fix: removed counting fields from scope initialisation and simplified handleParallelBranchCompletion to void; clean and correct
apps/sim/executor/orchestrators/node.ts Call sites updated to drop nodesInParallel arg and the count-based aggregation trigger; sentinel-end path unchanged and still calls aggregateParallelResults correctly
apps/sim/executor/execution/state.ts Removed completedCount and totalExpectedNodes from ParallelScope interface; remaining fields are correct
apps/sim/executor/types.ts Removed same two fields from the inline parallelExecutions map type in ExecutionContext; consistent with state.ts
apps/sim/executor/orchestrators/parallel.test.ts Updated call signature; no new regression test for the conditional-path bug scenario described in the PR
apps/sim/executor/utils/iteration-context.test.ts Removed completedCount/totalExpectedNodes from all fixture objects; mechanical cleanup, correct
apps/sim/executor/variables/resolvers/parallel.test.ts Removed the two fields from createParallelScope helper; mechanical cleanup, correct

Sequence Diagram

sequenceDiagram
    participant E as EdgeProcessor
    participant N as NodeExecutionOrchestrator
    participant P as ParallelOrchestrator
    participant S as ExecutionState

    Note over E,S: Branch node execution (per branch, per node)
    E->>N: executeNode(branchNode)
    N->>S: execute block
    S-->>N: output
    N->>N: handleNodeCompletion(branchNode)
    N->>P: handleParallelBranchCompletion(parallelId, nodeId, output)
    P->>P: branchOutputs.set(branchIndex, output)
    Note right of P: void — no count check

    Note over E,S: Sentinel-end reached (all branches finished via DAG edges)
    E->>N: executeNode(sentinel-end)
    N->>N: handleParallelSentinel(sentinelType=end)
    N->>P: aggregateParallelResults(parallelId)
    P->>P: collect branchOutputs[0..N]
    P->>S: setBlockOutput(parallelId, results)
    P-->>N: ParallelAggregationResult
    N-->>E: { results, sentinelEnd, selectedRoute: PARALLEL_EXIT }
Loading

Comments Outside Diff (1)

  1. apps/sim/executor/orchestrators/parallel.test.ts, line 110-121 (link)

    P2 Missing regression test for the bug scenario

    The PR description explains the exact failure mode: when a branch follows a conditional path (error edge, condition gate), it executes fewer nodes than a "full" branch, so completedCount never reached totalExpectedNodes. The existing tests exercise the empty-distribution and callback-failure paths, but there is no test that verifies:

    1. A parallel with N branches where at least one branch takes an early exit (e.g. an error edge skips a downstream node), and
    2. Aggregation still fires correctly via the sentinel-end — not via counting.

    Adding such a test would prevent a future regression if someone reintroduces count-based logic. Something like:

    it('aggregates results even when branches execute different numbers of nodes', async () => {
      // set up a parallel with 2 branches where branch-1 has fewer nodes executed
      // call handleParallelBranchCompletion for each executed node
      // call aggregateParallelResults (simulating sentinel-end trigger)
      // verify results contain both branches regardless of node counts
    })

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Reviews (1): Last reviewed commit: "fix(parallel): remove broken node-counti..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant