This document explains how workflows execute other workflows inline through the Workflow block (BlockType.WORKFLOW and BlockType.WORKFLOW_INPUT). It covers implementation details of the WorkflowBlockHandler, call chain validation for cycle detection, depth limits for resource management, trace span aggregation, and the instance-based correlation mechanism that allows the UI to render nested executions.
For information about loop and parallel subflow execution, see 3.5 Loop & Parallel Execution For human-in-the-loop pause/resume mechanics, see 3.14 Human-in-the-Loop & Paused Executions
The WorkflowBlockHandler is the core engine for nested execution. It creates a sub-executor with an isolated ExecutionContext while maintaining a link to the parent.
Sources: apps/sim/executor/handlers/workflow/workflow-handler.ts38-40
Diagram: Nested Workflow Handler Execution Flow
The handler implements executeWithNode to support execution within loops or parallel branches, passing nodeMetadata to preserve iteration context apps/sim/executor/handlers/workflow/workflow-handler.ts54-61
Sources: apps/sim/executor/handlers/workflow/workflow-handler.ts63-258 apps/sim/executor/handlers/workflow/workflow-handler.ts84-93
To prevent infinite recursion and manage system resources, the platform enforces hard limits on nesting.
The system tracks the sequence of workflow IDs in the current execution path using a "Call Chain".
X-Sim-Via header (SIM_VIA_HEADER) apps/sim/lib/execution/call-chain.ts27-29validateCallChain function checks if the chain length exceeds MAX_CALL_CHAIN_DEPTH (25) apps/sim/lib/execution/call-chain.ts11-14While execution can go 25 levels deep, real-time UI updates (via Server-Sent Events) are limited to a shallower depth to prevent browser performance degradation.
| Constant | Value | Description |
|---|---|---|
MAX_CALL_CHAIN_DEPTH | 25 | Maximum allowed nesting for workflow execution apps/sim/lib/execution/call-chain.ts11 |
MAX_SSE_CHILD_DEPTH | 3 | Maximum depth for propagating onBlockStart/Complete callbacks apps/sim/executor/constants.ts162 |
Sources: apps/sim/lib/execution/call-chain.ts38-51 apps/sim/executor/handlers/workflow/workflow-handler.ts86-93 apps/sim/executor/handlers/workflow/workflow-handler.ts148-156
A critical challenge in nested execution is attributing child block events (e.g., "LLM Block started") to the correct parent "Workflow Block", especially when that parent is inside a loop.
WorkflowBlockHandler generates a unique instanceId (UUID) for every single invocation of a workflow block apps/sim/executor/handlers/workflow/workflow-handler.ts84onChildWorkflowInstanceReady, passing the instanceId and the parent's iterationContext apps/sim/executor/handlers/workflow/workflow-handler.ts163-168childWorkflowInstanceId apps/sim/lib/workflows/executor/execution-events.ts184-186When a child workflow finishes, its internal block logs are converted into TraceSpan objects and attached to the parent block's output.
Diagram: Child Trace Span Aggregation
The transformSpanForChildWorkflow function ensures that spans coming from a child are clearly marked with isFromChildWorkflow: true and the childWorkflowName for clear debugging in the logs apps/sim/executor/handlers/workflow/workflow-handler.ts497-518
Sources: apps/sim/executor/handlers/workflow/workflow-handler.ts464-495 apps/sim/executor/handlers/workflow/workflow-handler.ts520-543 apps/sim/lib/logs/execution/trace-spans/trace-spans.ts1-6
Child workflows receive data through two primary mechanisms:
The lazyCleanupInputMapping utility is used to ensure that the mapping is sanitized against the child's current block structure before execution apps/sim/executor/handlers/workflow/workflow-handler.ts127-132
The handler respects the environment of the parent:
checkChildDeployment to ensure the child is also deployed apps/sim/executor/handlers/workflow/workflow-handler.ts98-104loadChildWorkflowDeployed to fetch the immutable versioned state apps/sim/executor/handlers/workflow/workflow-handler.ts107Sources: apps/sim/executor/handlers/workflow/workflow-handler.ts121-140 apps/sim/executor/handlers/workflow/workflow-handler.ts326-381 apps/sim/executor/handlers/workflow/workflow-handler.ts383-400
Nested workflows share the parent's abortSignal. If a parent execution is cancelled, the signal propagates to the child's subExecutor, ensuring resources are freed immediately apps/sim/executor/handlers/workflow/workflow-handler.ts183
Errors in child workflows are caught and wrapped in a ChildWorkflowError apps/sim/executor/errors/child-workflow-error.ts1-19 This error includes the child's name and ID, allowing the useWorkflowExecution hook to provide a "breadcrumb" style error message to the user apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts:78-102.
Sources: apps/sim/executor/handlers/workflow/workflow-handler.ts208-220 apps/sim/executor/handlers/workflow/workflow-handler.ts183
Refresh this wiki