This document describes how Sim resolves references to block outputs, workflow variables, loop context, and workflow inputs during execution. The resolution engine translates reference syntax (e.g., {{blockName.output}} or <variable.varName>) into runtime values by querying the ExecutionContext.
The resolution system handles:
<blockId.output.field> syntax for accessing previous block results.<variable.varName> references to workflow-scoped variables.<loop.index>, <loop.item> for iteration-specific data.<parallel.index>, <parallel.currentItem> for branch-specific data.{{ENV_VAR}} syntax for environment variable substitution.Sim supports multiple reference syntaxes for accessing different data sources during workflow execution. The BlockResolver and VariableResolver are the primary classes responsible for this translation.
Diagram: Reference Syntax Patterns
| Syntax Pattern | Example | Resolves To |
|---|---|---|
<blockId.output> | <function1.result> | Output from block with ID or Name function1 |
<variable.varName> | <variable.apiKey> | Workflow variable named apiKey |
<loop.index> | <loop.index> | Current loop iteration number (0-based) |
<loop.item> | <loop.item> | Current item in forEach loop |
<parallel.index> | <parallel.index> | Current parallel branch index |
{{ENV_VAR}} | {{DATABASE_URL}} | Environment variable value |
Sources: apps/sim/executor/constants.ts116-152 apps/sim/executor/variables/resolvers/block.ts22-47
The BlockResolver handles the resolution of data produced by previously executed blocks. It maps block names to internal IDs and navigates nested JSON output structures.
Block names are normalized for case-insensitive matching using normalizeName() apps/sim/executor/constants.ts277-308 The BlockResolver maintains a mapping of these normalized names to blockId apps/sim/executor/variables/resolvers/block.ts23-35
Diagram: Block Output Data Flow
ExecutionState or the local ResolutionContext apps/sim/executor/variables/resolvers/block.ts149-160resolveBlockReference, it navigates the path (e.g., .result.data) within the output object apps/sim/executor/variables/resolvers/block.ts78-86response or workflow_input to ensure old reference paths still resolve apps/sim/executor/variables/resolvers/block.ts106-147Sources: apps/sim/executor/variables/resolvers/block.ts49-104 apps/sim/lib/copilot/orchestrator/tool-executor/workflow-tools/queries.ts5-6
The resolveExecutorStartBlock function determines which block serves as the entry point for execution and how its inputs are structured apps/sim/executor/utils/start-block.ts32-35
Sim utilizes a unified output format for trigger blocks to simplify downstream references. This is handled by buildUnifiedStartOutput which merges input fields, files, and conversation IDs into a consistent object apps/sim/executor/utils/start-block.ts259-300
Trigger blocks support an inputFormat sub-block that defines expected parameters apps/sim/triggers/generic/webhook.ts105-111 The coerceValue function ensures that incoming data (from webhooks or manual runs) matches the defined types:
NaN apps/sim/executor/utils/start-block.ts144-148JSON.parse if the input is a string apps/sim/executor/utils/start-block.ts155-166Sources: apps/sim/executor/utils/start-block.ts136-170 apps/sim/executor/utils/start-block.ts178-224
The useAccessibleReferencePrefixes hook is the primary mechanism for the UI to determine which blocks are available for referencing within a specific block's configuration apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes.ts:9-17.
A block can only reference outputs from its ancestors in the Directed Acyclic Graph (DAG). The BlockPathCalculator.findAllPathNodes function computes these ancestors apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes.ts:24-27.
The hook also adds context-specific prefixes if the block is located inside a loop or parallel subflow:
blockId is contained within loop.nodes, the loop.id and its normalized name are added to the accessible prefixes apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes.ts:29-31.parallel.id becomes an accessible prefix apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes.ts:33-35.Sources: apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes.ts:19-50, apps/sim/lib/workflows/blocks/block-path-calculator.ts1-5
Before a workflow is executed, the Serializer class transforms the frontend state into a SerializedWorkflow suitable for the engine apps/sim/serializer/index.ts146-152
During serialization, the engine can perform validateRequired checks. For subflow blocks (loops/parallels), it ensures that required inputs are mapped correctly apps/sim/serializer/index.ts184-191
The serializer also handles legacy variable formats. For example, migrateAgentParamsToMessages converts old systemPrompt and userPrompt fields into the modern messages array format, preserving variable references embedded within those strings apps/sim/serializer/index.ts93-143
Sources: apps/sim/serializer/index.ts158-160 apps/sim/serializer/index.test.ts32-55
When references are used inside Function blocks (JavaScript/Python) or Condition blocks, they must be formatted as code literals rather than raw strings.
The formatValueForBlock method in BlockResolver handles this:
stringifyForCondition to escape quotes and newlines for safe inclusion in a JS expression apps/sim/executor/variables/resolvers/block.ts192-211formatValueForCodeContext to generate language-specific literals (e.g., Python None vs JS null) apps/sim/executor/variables/resolvers/block.ts213-215Sources: apps/sim/executor/variables/resolvers/block.ts166-190 apps/sim/executor/utils/code-formatting.ts1-20
The VariableResolver orchestrates multiple specialized resolvers to process strings containing mixed text and references.
Diagram: Resolver Orchestration
resolveInputs: Iterates through block parameters and resolves any templates found within values apps/sim/executor/variables/resolver.ts39-44resolveTemplate: Uses replaceValidReferences to find <...> patterns and delegates to the appropriate resolver apps/sim/executor/variables/resolver.ts152-197resolveSingleReference: Specifically handles cases where a field contains exactly one reference, allowing the return of non-string types (like objects or arrays) without casting to string apps/sim/executor/variables/resolver.ts95-120Sources: apps/sim/executor/variables/resolver.ts20-37 apps/sim/executor/variables/resolver.ts152-208
| Class/Function | File | Role |
|---|---|---|
BlockResolver | apps/sim/executor/variables/resolvers/block.ts | Resolves <blockName.path> references by mapping names to block outputs. |
VariableResolver | apps/sim/executor/variables/resolver.ts | The main entry point for variable resolution during execution. |
Serializer | apps/sim/serializer/index.ts | Prepares workflow state and migrates legacy variable formats for the executor. |
useAccessibleReferencePrefixes | apps/sim/app/workspace/.../use-accessible-reference-prefixes.ts | Hook for filtering available reference tags based on DAG topology. |
ExecutionState | apps/sim/executor/execution/state.ts | Stores actual runtime values of block outputs and loop indices. |
Sources: apps/sim/executor/variables/resolvers/block.ts22 apps/sim/executor/variables/resolver.ts20 apps/sim/serializer/index.ts145 apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes.ts:9
Refresh this wiki