Parallel group execution sequence error #7782

Closed
opened 2026-02-21 18:22:21 -05:00 by yindo · 7 comments
Owner

Originally created by @Nickqiaoo on GitHub (Jan 19, 2025).

Originally assigned to: @laipz8200, @Nov1c444, @crazywoola on GitHub.

Self Checks

  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report (我已阅读并同意 Language Policy).
  • [FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)
  • Please do not modify this template :) and fill in all the required fields.

Dify version

cloud version

Cloud or Self Hosted

Cloud

Steps to reproduce

Image
I create a workflow like this, I think 5 should wait for the completion of 1 and 2 before running, but in reality, 5 ran multiple times.

✔️ Expected Behavior

5 should wait for the completion of 1 and 2 before running, 6 and 7 are also.

Actual Behavior

5 6 7 has been run multiple times.

Originally created by @Nickqiaoo on GitHub (Jan 19, 2025). Originally assigned to: @laipz8200, @Nov1c444, @crazywoola on GitHub. ### Self Checks - [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general). - [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones. - [x] I confirm that I am using English to submit this report (我已阅读并同意 [Language Policy](https://github.com/langgenius/dify/issues/1542)). - [x] [FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:) - [x] Please do not modify this template :) and fill in all the required fields. ### Dify version cloud version ### Cloud or Self Hosted Cloud ### Steps to reproduce ![Image](https://github.com/user-attachments/assets/c0992724-241b-4451-a88b-a7b094412159) I create a workflow like this, I think 5 should wait for the completion of 1 and 2 before running, but in reality, 5 ran multiple times. ### ✔️ Expected Behavior 5 should wait for the completion of 1 and 2 before running, 6 and 7 are also. ### ❌ Actual Behavior 5 6 7 has been run multiple times.
yindo added the 🐞 bug🌊 feat:workflow labels 2026-02-21 18:22:21 -05:00
yindo closed this issue 2026-02-21 18:22:22 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jan 19, 2025):

@Nickqiaoo Hello there! I'm here to help you with bug reports, questions, and becoming a contributor. Let's tackle this issue together while we wait for a human maintainer.

I found a similar unsolved discussion regarding parallel execution issues in Dify. The discussion mentions a major issue with parallel execution in the workflow, where the issue classifier was treated as a parallel execution branch [1].

In Dify, parallel execution of nodes is managed using a ThreadPoolExecutor, which allows for concurrent execution. However, if nodes are running multiple times unexpectedly, it might be due to how dependencies are defined or managed in the workflow. The current implementation logic for handling dependencies involves recursively fetching dependencies for each node, ensuring that nodes wait for their dependencies to complete before execution [2][3].

To address the issue you're facing, you might want to check the configuration of your workflow to ensure that dependencies are correctly defined. This includes verifying that nodes 5, 6, and 7 are set to wait for the completion of their preceding nodes (1 and 2) before execution. Additionally, reviewing the error handling strategies and retry configurations might help, as these can affect node execution behavior [4][5].

If the problem persists, consider exploring the workflow's concurrency management settings, such as the maximum number of concurrent threads and the error handling strategies in place, to ensure they align with your expected execution flow [6][7].

To continue talking to Dosu, mention @dosu.


Help Dosu learn! Give it feedback: Great Response | Irrelevant Answer | Incorrect Sources | Too Verbose | Hallucination | Other

@dosubot[bot] commented on GitHub (Jan 19, 2025): <!-- Greeting --> @Nickqiaoo Hello there! I'm here to help you with bug reports, questions, and becoming a contributor. Let's tackle this issue together while we wait for a human maintainer. <!-- Answer --> I found a similar unsolved discussion regarding parallel execution issues in Dify. The discussion mentions a major issue with parallel execution in the workflow, where the issue classifier was treated as a parallel execution branch <sup>[[1]](https://github.com/langgenius/dify/discussions/8285)</sup>. In Dify, parallel execution of nodes is managed using a `ThreadPoolExecutor`, which allows for concurrent execution. However, if nodes are running multiple times unexpectedly, it might be due to how dependencies are defined or managed in the workflow. The current implementation logic for handling dependencies involves recursively fetching dependencies for each node, ensuring that nodes wait for their dependencies to complete before execution <sup>[[2]](https://github.com/langgenius/dify/blob/main/api/core/workflow/nodes/answer/answer_stream_generate_router.py)</sup><sup>[[3]](https://github.com/langgenius/dify/blob/main/api/core/workflow/nodes/end/end_stream_generate_router.py)</sup>. To address the issue you're facing, you might want to check the configuration of your workflow to ensure that dependencies are correctly defined. This includes verifying that nodes 5, 6, and 7 are set to wait for the completion of their preceding nodes (1 and 2) before execution. Additionally, reviewing the error handling strategies and retry configurations might help, as these can affect node execution behavior <sup>[[4]](https://github.com/langgenius/dify-docs/blob/main/en/guides/workflow/error-handling/README.md)</sup><sup>[[5]](https://github.com/langgenius/dify-docs/blob/main/zh_CN/guides/workflow/error-handling/README.md)</sup>. If the problem persists, consider exploring the workflow's concurrency management settings, such as the maximum number of concurrent threads and the error handling strategies in place, to ensure they align with your expected execution flow <sup>[[6]](https://github.com/langgenius/dify/blob/main/api/core/workflow/graph_engine/graph_engine.py)</sup><sup>[[7]](https://github.com/langgenius/dify/blob/main/api/tests/unit_tests/core/workflow/nodes/iteration/test_iteration.py)</sup>. <!-- Dosu Comment Footer --> *To continue talking to [Dosu](https://dosu.dev), mention @dosu.* --- <sup>Help Dosu learn! Give it feedback: [Great Response](https://app.dosu.dev/response-feedback/df1d5da4-ae1c-412a-914e-bb3614325e65?feedback_type=great_response) | [Irrelevant Answer](https://app.dosu.dev/response-feedback/df1d5da4-ae1c-412a-914e-bb3614325e65?feedback_type=irrelevant_answer) | [Incorrect Sources](https://app.dosu.dev/response-feedback/df1d5da4-ae1c-412a-914e-bb3614325e65?feedback_type=incorrect_sources) | [Too Verbose](https://app.dosu.dev/response-feedback/df1d5da4-ae1c-412a-914e-bb3614325e65?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/df1d5da4-ae1c-412a-914e-bb3614325e65?feedback_type=hallucination) | [Other](https://app.dosu.dev/response-feedback/df1d5da4-ae1c-412a-914e-bb3614325e65?feedback_type=other)</sup>
Author
Owner

@Jhvcc commented on GitHub (Jan 24, 2025):

In graph_engine.py, it seems to only use graph.edge_mapping but not use graph.reverse_edge_mapping to verify that all pre-inputs are completed before running the node.

@Jhvcc commented on GitHub (Jan 24, 2025): In __graph_engine.py__, it seems to only use `graph.edge_mapping` but not use `graph.reverse_edge_mapping` to verify that all pre-inputs are completed before running the node.
Author
Owner

@icowan commented on GitHub (Feb 9, 2025):

遇到了一样的问题了

@icowan commented on GitHub (Feb 9, 2025): 遇到了一样的问题了
Author
Owner

@Nickqiaoo commented on GitHub (Feb 18, 2025):

I read the code related to graphs, and the general processing flow is as follows:
1. The starting points for parallel execution can be either regular nodes or conditional nodes. First, a parallelMap is used to store the starting nodes and the nodes that need to be executed in parallel from these starting points.
2. Traverse the parallelMap, and for each starting point, get all the nodes that can be reached through the branches connected to the starting point. Then, traverse all the reachable nodes on each branch to identify merge nodes. The criterion for identifying merge nodes is that if a node has an in-degree greater than 1 and appears on the paths of other branches, it is considered a merge node.
3. Use a mergeMap to record which branches contain the merge nodes. When two merge nodes appear in the exact same branches, retain the one that appears first, then sort them in descending order based on the number of branches, recording the merge node for each branch (the descending order is to prioritize the merge nodes that appear in the most branches).
4. Collect all the nodes from the starting point to the merge node for each branch, storing them in a branchnodeMap. These nodes are assigned a parallelID to indicate that they belong to this parallel group.
5. Traverse all the nodes in branchnodeMap, and if a node meets the following condition: it has only one outgoing edge, and the target node of this edge does not belong to the current parallel group or its parent parallel group, then set this target node as the end node for the current parallel group, i.e., the merge node.

During execution, as long as the nodes belong to the same parallel group, they are executed in parallel. After the parallel group finishes execution, the end node of the parallel group is returned as the next node to continue execution.

If the graph is like this:

graph LR;
    START --> 1;
    START --> 2;
    START --> 4;
    1 --> 3;
    2 --> 3;
    3 --> 5;
    5 --> 6;
    4 --> 5;

Since nodes 1, 2, 3, and 4 are grouped into a parallel group and node 5 is the merge node, in parallel execution, the parallel branches are (1 3), (2 3), and (4). Node 3 is executed twice. I believe the root cause of the problem is that the parallel group division is not reasonable.

@Nickqiaoo commented on GitHub (Feb 18, 2025): I read the code related to graphs, and the general processing flow is as follows: 1. The starting points for parallel execution can be either regular nodes or conditional nodes. First, a parallelMap is used to store the starting nodes and the nodes that need to be executed in parallel from these starting points. 2. Traverse the parallelMap, and for each starting point, get all the nodes that can be reached through the branches connected to the starting point. Then, traverse all the reachable nodes on each branch to identify merge nodes. The criterion for identifying merge nodes is that if a node has an in-degree greater than 1 and appears on the paths of other branches, it is considered a merge node. 3. Use a mergeMap to record which branches contain the merge nodes. When two merge nodes appear in the exact same branches, retain the one that appears first, then sort them in descending order based on the number of branches, recording the merge node for each branch (the descending order is to prioritize the merge nodes that appear in the most branches). 4. Collect all the nodes from the starting point to the merge node for each branch, storing them in a branchnodeMap. These nodes are assigned a parallelID to indicate that they belong to this parallel group. 5. Traverse all the nodes in branchnodeMap, and if a node meets the following condition: it has only one outgoing edge, and the target node of this edge does not belong to the current parallel group or its parent parallel group, then set this target node as the end node for the current parallel group, i.e., the merge node. During execution, as long as the nodes belong to the same parallel group, they are executed in parallel. After the parallel group finishes execution, the end node of the parallel group is returned as the next node to continue execution. If the graph is like this: ```mermaid graph LR; START --> 1; START --> 2; START --> 4; 1 --> 3; 2 --> 3; 3 --> 5; 5 --> 6; 4 --> 5; ``` Since nodes 1, 2, 3, and 4 are grouped into a parallel group and node 5 is the merge node, in parallel execution, the parallel branches are (1 3), (2 3), and (4). Node 3 is executed twice. I believe the root cause of the problem is that the parallel group division is not reasonable.
Author
Owner

@Nickqiaoo commented on GitHub (Feb 21, 2025):

To solve this problem, I propose this solution: if a node's parallel branches are followed by multiple merge nodes, it indicates that some branches have merged prematurely. To be compatible with the existing parallel group algorithm, I will add a segment of processing code. Before these prematurely merged branches, some virtual nodes will be inserted to ensure the normal operation of the existing parallel group algorithm, minimizing code changes.
Just like this:
Before:

graph LR;
    START["START"] --> 1;
    START --> 2;
    START --> 3;
    START --> 4;
    1 --> 5;
    2 --> 5;
    5 --> 6;
    3 --> 6;
    6 --> 7;
    4 --> 7;

After:

graph LR;
    START --> v2;
    START --> 4;
    v1 --> 1;
    v1 --> 2;
    v2 --> v1;
    v2 --> 3;
    1 --> 5;
    2 --> 5;
    3 --> 6;
    5 --> 6;
    4 --> 7;
    6 --> 7;
@Nickqiaoo commented on GitHub (Feb 21, 2025): To solve this problem, I propose this solution: if a node's parallel branches are followed by multiple merge nodes, it indicates that some branches have merged prematurely. To be compatible with the existing parallel group algorithm, I will add a segment of processing code. Before these prematurely merged branches, some virtual nodes will be inserted to ensure the normal operation of the existing parallel group algorithm, minimizing code changes. Just like this: Before: ```mermaid graph LR; START["START"] --> 1; START --> 2; START --> 3; START --> 4; 1 --> 5; 2 --> 5; 5 --> 6; 3 --> 6; 6 --> 7; 4 --> 7; ``` After: ```mermaid graph LR; START --> v2; START --> 4; v1 --> 1; v1 --> 2; v2 --> v1; v2 --> 3; 1 --> 5; 2 --> 5; 3 --> 6; 5 --> 6; 4 --> 7; 6 --> 7; ```
Author
Owner

@leezhiranGit commented on GitHub (Feb 23, 2025):

Same issue here.

@leezhiranGit commented on GitHub (Feb 23, 2025): Same issue here.
Author
Owner

@dosubot[bot] commented on GitHub (Apr 5, 2025):

Hi, @Nickqiaoo. I'm Dosu, and I'm helping the Dify team manage their backlog. I'm marking this issue as stale.

Issue Summary:

  • You reported a bug in the parallel group execution sequence in Dify's cloud version.
  • Tasks 5, 6, and 7 were running multiple times instead of waiting for tasks 1 and 2.
  • You identified the root cause as an unreasonable parallel group division.
  • A solution was proposed involving the insertion of virtual nodes to ensure proper execution flow.
  • Other users confirmed experiencing similar issues.

Next Steps:

  • Please let me know if this issue is still relevant to the latest version of the Dify repository by commenting on this issue.
  • If there is no further activity, I will automatically close this issue in 15 days.

Thank you for your understanding and contribution!

@dosubot[bot] commented on GitHub (Apr 5, 2025): Hi, @Nickqiaoo. I'm [Dosu](https://dosu.dev), and I'm helping the Dify team manage their backlog. I'm marking this issue as stale. **Issue Summary:** - You reported a bug in the parallel group execution sequence in Dify's cloud version. - Tasks 5, 6, and 7 were running multiple times instead of waiting for tasks 1 and 2. - You identified the root cause as an unreasonable parallel group division. - A solution was proposed involving the insertion of virtual nodes to ensure proper execution flow. - Other users confirmed experiencing similar issues. **Next Steps:** - Please let me know if this issue is still relevant to the latest version of the Dify repository by commenting on this issue. - If there is no further activity, I will automatically close this issue in 15 days. Thank you for your understanding and contribution!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#7782