@ksoftm/n8n-nodes-dag-orchestrator
v2.1.0
Published
Blueprint-Style DAG Workflow Orchestrator for n8n
Maintainers
Readme
n8n-nodes-dag-orchestrator
Blueprint-Style DAG Workflow Orchestration for n8n
Bring Unreal Engine Blueprint-style visual workflow orchestration to n8n. Instead of a single node with raw JSON config, use seven purpose-built, visually connected nodes to build parallel workflows with full dependency management, error handling, and binary data preservation.
What This Package Does
This community node package solves key n8n limitations:
- Parallel branches with dependency management — n8n cannot natively run parallel branches that wait for each other with complex logic
- Binary data preservation — binary data is lost in sub-workflows
- Nested loops without index corruption — loop index tracking breaks with nested loops
- Built-in error handling — try/catch/finally per branch without complex workflow setup
- Loop control — break/continue conditions without manual global state hacks
Build complex DAGs visually by connecting small, focused nodes—no JSON configs, no sub-workflows, no code required.
Installation
- In n8n, open Community Nodes (gear icon → Community Nodes)
- Search for dag-orchestrator
- Click Install
- Restart n8n
Or via npm (for development):
cd ~/.n8n/nodes # or your n8n user directory
npm install @ksoftm/n8n-nodes-dag-orchestratorThe Seven Nodes
| Node | Purpose | | ----------- | ------------------------------------------------------------------- | | DAG Split | Start a DAG, split input into parallel branches (2–6 outputs) | | DAG Try | Mark start of a branch, set retry/timeout, route to Success/Failure | | DAG Catch | Handle failures from DAG Try, recover or fail downstream | | DAG Finally | Always runs at end of branch for cleanup and status finalization | | DAG Join | Collect and merge results from all branches into one output | | DAG Loop | Loop over arrays with isolated index tracking, break/continue | | DAG Group | Group branches into a named logical container (subgraph) |
Visual Flow Example
┌─────────────────────────────────────────────────────────────────────┐
│ Image Processing Flow │
└─────────────────────────────────────────────────────────────────────┘
[Manual Trigger]
│
▼
[DAG Split] ←── branchCount: 3
│ │ │
│ │ └─────────────────────┐
│ │ │
│ ▼ │
│ [DAG Try] │
│ "metadata" │
│ │ Success │
│ ▼ │
│ [Code: extract] │
│ │ │
│ ▼ │
│ [DAG Finally] │
│ "metadata" │
│ │ │
▼ │ │
[DAG Try] [DAG Try] │
"image_storage" "thumbnail" │
│ Success │ Success │
▼ ▼ │
[HTTP: [Code: │
save to resize] │
Drive] │ │
│ ▼ │
│ [DAG Finally] │
│ "thumbnail" │
│ │ │
▼ ▼ ▼
[DAG Finally] ← [DAG Finally] ← [DAG Finally]
"image_storage" "metadata" "thumbnail"
│ │ │
└──────────────┼────────────────┘
▼
[DAG Join]
expectedBranchCount: 3
joinMode: waitForAll
outputFormat: merged
│
▼
[Next Node]
Result: {
branches: {
image_storage: { status: "completed", data: [...] },
metadata: { status: "completed", data: [...] },
thumbnail: { status: "completed", data: [...] }
}
}How It Works
- DAG Split creates a unique execution context and routes input to all branches
- DAG Try marks branch start, enforces retry/timeout policies, routes success/failure
- User nodes run on the success path
- DAG Catch (optional) recovers from failures
- DAG Finally marks branch completion, ensures all branches reach the join
- DAG Join waits for all branches using static data, merges results
- Binary data is preserved at every step
For loops, use DAG Loop to iterate without sub-workflows:
- Automatically tracks loop index and total items
- Routes each batch to "Loop Body" output
- Routes completion summary to "Done" output
- Supports break/continue conditions
Important Notes
Self-Hosted n8n Required
DAG Join and DAG Loop use getWorkflowStaticData('node') to maintain state across multiple execution calls. This feature is only available in self-hosted n8n. It does not work in n8n Cloud.
Verified Community Node Publishing
As of May 1, 2026, n8n requires verified community node publishing via GitHub Actions with provenance signatures. This package will comply with those requirements.
Binary Data is Preserved
Unlike sub-workflows, all nodes in this package preserve binary data at every step. Binary buffers are never serialized—they stay in memory throughout the workflow execution.
Error Handling with DAG Try and DAG Catch
DAG Try and DAG Catch provide try/catch error handling per branch. However, since n8n workflows execute asynchronously, the "catch" block cannot wrap downstream operations directly. Instead, use n8n's built-in error outputs to route failures back to DAG Catch.
Wiring Pattern for Error Handling
- Connect DAG Try to your operation nodes (e.g., HTTP Request, AI Agent).
- On the operation node, enable "Continue On Fail" in its settings.
- Connect the operation node's Error Output (red pin) back to a DAG Catch node.
- Connect the operation node's Success Output (green pin) to DAG Finally.
- DAG Catch can then recover (fallback data) or rethrow the error.
[DAG Try]
↓ Success
[Operation Node] ←── Enable "Continue On Fail"
├─ Success ──→ [DAG Finally]
└─ Error ────→ [DAG Catch]
↓
[Recovery Logic or Rethrow]Example: API Call with Retry and Fallback
[DAG Try] (timeout: 30s, retry: 2)
↓ Success
[HTTP Request] (Continue On Fail: ON)
├─ Success ──→ [Process Response] → [DAG Finally]
└─ Error ────→ [DAG Catch] (recoveryMode: fallback)
↓
[Use Fallback Data] → [DAG Finally]- If the HTTP request succeeds, data flows to DAG Finally.
- If it fails (e.g., 500 error), the error output routes to DAG Catch, which injects fallback data and continues.
- DAG Finally always runs, marking the branch as completed or failed.
Important Notes
- DAG Try's Error output is for its own internal failures (rare). For downstream errors, wire from the operation node's error output.
- Use DAG Catch's
rethrowmode to propagate errors upward if recovery isn't possible. - Error details are stored in
item.json._dagErrorfor inspection.
Connection Rules
Valid patterns:
Pattern A: Parallel Branches with Error Handling
[Any Node]
↓
[DAG Split]
↙ ↓ ↘
[DAG Try] [DAG Try] [DAG Try]
│ Success ↓ Success ↓ Success
├────────→[ops]→[ops]→
│ │ Failure
├─────────→[DAG Catch]
│ ↓
├────────────────[DAG Finally]
│ │ │
└─→ ↓ ↓
[DAG Join]
↓
[Any Node]
Pattern B: Looping
[Any Node]
↓
[DAG Loop] ←──────────┐
↙ ↘ │
[Loop Body] [Done] │
↓ │
[ops] → [repeat?] ────┘
↓
[Next Step]
Pattern C: Grouped DAGs
[Any Node] → [DAG Group] → [DAG Split] → ... → [DAG Join] → [Any Node]
Pattern D: Nested Groups
[DAG Group] → [DAG Split] → [DAG Group] → [DAG Split] → [DAG Join] → [DAG Join]Context Fields
Every item carries DAG context in item.json. Key fields:
_dagExecutionId; // Unique ID for this DAG run
_dagBranchLabel; // e.g., "image_storage", "metadata"
_dagStatus; // "running" | "try_running" | "completed" | "failed" | ...
_dagError; // Error message if failed
_dagTimeoutMs; // Timeout in ms (set by DAG Try)
_dagMaxRetry; // Max retry attempts
_dagRetryDelayMs; // Delay between retries
_dagLoopId; // Loop ID (DAG Loop)
_dagGroupLabel; // Group name (DAG Group)See the specification document for the complete field reference.
Examples
Image Processing (Binary + Parallel)
Receive an image, save to Drive AND extract metadata in parallel, then generate thumbnail.
Manual Trigger
↓
[DAG Split: 3 branches]
↙ ↓ ↘
Save Extract Thumbnail
↓ ↓ ↓
DAG Try (timeout: 60s, retry: 3)
↓
[HTTP POST to Drive]
↓
[DAG Finally]
↓
[DAG Join]
↓
[Next Step - Use Merged Results]API Rate-Limited Fetches (Loops)
Fetch 1000 items from an API with low rate limits.
[API: Get Total Count] → result: 1000
↓
[DAG Loop]
├─ Source Field: items
├─ Batch Size: 10
├─ Max Iterations: 100
│
├─[Loop Body]
│ ↓
│ [HTTP GET] with offset + limit
│ ↓
│ [Transform Result]
│ ↓
│ [repeat loop]
│
└─[Done] → [Combine All Results]Troubleshooting
"DAG Join returns empty and never emits"
- Check
expectedBranchCountmatchesbranchCountin DAG Split - Check all branches actually reach DAG Join (connection paths should be visible in n8n UI)
- Check
joinMode— ifwaitForAll, ensure all branches complete
"Loop runs forever"
- Set a
maxIterationslimit - Use
breakConditionto exit early - Check source array is actually provided
"Binary data is lost"
- This package preserves binary. If lost, check upstream nodes before DAG Split
- Ensure DAG Split is used as starting point if binary input is needed
License
MIT
Support
For issues, questions, or feature requests, visit the GitHub repository.
Publishing & Verification
- All six nodes must be registered in
package.jsonundern8n.nodes npm run lintandnpm run buildmust pass- README must describe the new multi-node system
- Version must be bumped for major changes
- From May 2026, GitHub Actions provenance is required for verification
Credits
- Inspired by Unreal Engine Blueprints
- Built for the n8n community
