Run-from-block debugging enables partial workflow re-execution starting from a specific block while reusing cached outputs from a previous execution. This feature allows iterative development and debugging by re-running only the portion of a workflow that changed, significantly reducing execution time and cost during development.
For information about full workflow execution, see Workflow Execution Engine. For execution state persistence, see State Persistence.
Run-from-block execution operates by computing a dirty set of blocks that require re-execution (the start block and all downstream dependencies) and reusing cached outputs from upstream blocks. The execution engine loads a previous execution snapshot, filters it to relevant blocks, and modifies the Directed Acyclic Graph (DAG) to prevent waiting on cached dependencies.
| Concept | Description |
|---|---|
| Start Block | The block from which to resume execution. |
| Source Snapshot | Execution state from a previous run containing cached block outputs. |
| Dirty Set | Blocks that will be re-executed (start block + all downstream). |
| Upstream Set | All blocks that execute before the start block. |
| Reachable Upstream Set | Blocks whose outputs may be referenced by dirty blocks (includes sibling branches). |
Sources: apps/sim/executor/execution/executor.ts105-126 apps/sim/app/api/workflows/[id]/execute/route.ts:94-116
The run-from-block feature is invoked via the workflow execution API POST /api/workflows/[id]/execute with the runFromBlock parameter. The request can provide either a pre-loaded snapshot or an execution ID to load the snapshot from storage.
Title: Run-from-Block Request Flow
Sources: apps/sim/app/api/workflows/[id]/execute/route.ts:94-116, apps/sim/app/api/workflows/[id]/execute/route.ts:51-53, apps/sim/lib/workflows/executor/execution-core.ts48-52
The execution request schema in ExecuteWorkflowSchema accepts a runFromBlock object:
Sources: apps/sim/app/api/workflows/[id]/execute/route.ts:94-116
The executeFromBlock() method in DAGExecutor (exported as Executor) computes three critical sets to determine execution scope. This logic is handled during the transition from cached state to active execution.
Title: Code Entity Space - Execution Logic
Sources: apps/sim/executor/index.ts6 apps/sim/executor/execution/executor.ts105-126
| Set | Contents | Purpose |
|---|---|---|
| dirtySet | Start block and all downstream dependencies. | Blocks that will be re-executed. |
| upstreamSet | All blocks that execute before start block. | Blocks with cached outputs. |
| reachableUpstreamSet | Upstream set + sibling branches. | Blocks whose outputs are preserved for variable resolution. |
Sources: apps/sim/executor/execution/executor.ts116-126
To ensure the engine doesn't hang waiting for cached blocks, the DAGExecutor modifies the DAG in-memory by removing incoming edges to "dirty" blocks that originate from "non-dirty" (cached) blocks.
Title: DAG Edge Pruning for Re-execution
Sources: apps/sim/executor/execution/executor.ts175-191
The filtered snapshot is used to populate the ExecutionContext. The reachableUpstreamSet ensures that if a dirty block references a variable from a sibling branch (e.g., {{previous_branch.output}}), that data is available even if previous_branch isn't re-executed.
Sources: apps/sim/executor/execution/executor.ts116-165 apps/sim/executor/types.ts184-185
Once the environment is prepared, BlockExecutor.execute is called for the dirty blocks. It uses a VariableResolver to resolve inputs, which may pull from the hydrated blockStates (cached) or newly generated outputs.
Title: Natural Language to Code Entity Mapping
Sources: apps/sim/executor/execution/block-executor.ts51-125 apps/sim/executor/types.ts184-187
VariableResolver checks ctx.blockStates. If the block is cached, its output is retrieved. If it's dirty, the resolver looks for the source in blockStates (which contains both cached and new results).BlockExecutor finds the appropriate BlockHandler (e.g., WorkflowBlockHandler for nested workflows).BlockStateWriter.BlockLog entries are generated with an executionOrder produced by getNextExecutionOrder() to ensure deterministic ordering in the UI.Sources: apps/sim/executor/execution/block-executor.ts101-125 apps/sim/executor/execution/block-executor.ts182-183 apps/sim/executor/types.ts34-36 apps/sim/executor/handlers/workflow/workflow-handler.ts38-44
The useWorkflowExecution hook manages the UI state for debugging. It tracks isDebugging, pendingBlocks, and coordinates the runFromBlock logic.
Title: Client Debug State Management
Sources: apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts:106-115, apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts:128-132, apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts:166-180
executor and debugContext are present before a partial run.pendingBlocks and activeBlocks sets in the useExecutionStore to prepare for a fresh debug iteration.useTerminalConsoleStore receives updates via SSE events, which are processed by createBlockEventHandlers.Sources: apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts:166-180, apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils.ts:132-151, apps/sim/stores/terminal/console/store.ts26-30
When a block fails, run-from-block allows re-running from that block after fixing configuration:
agent-1.agent-1.runFromBlock: { startBlockId: 'agent-1', executionId: 'last-id' }.agent-1 and downstream blocks execute; upstream outputs are reused from blockStates.During prompt engineering, run-from-block avoids re-executing expensive upstream API calls:
Sources: apps/sim/executor/execution/executor.ts166-174 apps/sim/app/api/workflows/[id]/execute/route.ts:94-116
Refresh this wiki