The Context Object is the central runtime state container for every workflow execution—capturing inputs, node states, outputs, and metadata across the full lifecycle of a run.
Overview
Every workflow execution has a single Context Object that updates dynamically as the workflow progresses. It serves as the shared memory layer that nodes read from and write to, enabling data to flow through the entire pipeline.
What it tracks:
- Run Metadata - Identifiers, timestamps, and workflow configuration (
startDate, status, flowType, appId, versionId, cfProcessId)
- Execution State - Each node’s progress and outcome (
steps, branch, activeSteps)
- Environment & Config - Runtime parameters and settings (
env, agentTimeout, asyncExecDetails)
Structure
Top-Level Fields
| Category | Key Fields | Description |
|---|
| Run Metadata | startDate, status, flowType, appId, versionId, cfProcessId | Identifiers and timestamps for the workflow instance |
| Execution State | steps, branch, activeSteps, status | Each node’s progress and outcome |
| Environment & Config | env, agentTimeout, asyncExecDetails | Runtime and environment parameters |
The steps Object
steps is the most critical part of the Context Object—a map indexed by node name or ID that holds the state of each node in the workflow.
"steps": {
"NodeNameA": { ... },
"NodeNameB": { ... },
"NodeNameC": { ... }
}
Each node entry contains:
| Field | Description |
|---|
input | Data received by the node at execution time, from previous nodes or user input |
output | Result produced by the node—model outputs, processed data, or API responses |
statusCode / isSuccessful | Whether execution succeeded, failed, or was skipped |
logs | Log text or debug messages generated by the node |
executionTime, totalTime, pausedAt, resumedAt | Node-level timing data |
reqObj / resObj | For model-invoking nodes: raw request and response envelopes |
metadata | Node-specific information such as schema references, task IDs, or external job handles |
Example node structure:
"steps": {
"ExampleNode": {
"input": {
"parameters": { "param1": "value1" },
"contextRefs": { "previousNodeOutput": "..." }
},
"output": {
"result": "some value",
"summary": "optional explanation",
"structuredData": { "key": "value" }
},
"statusCode": 200,
"isSuccessful": true,
"logs": "Node executed successfully",
"executionTime": "1250ms",
"reqObj": {
"endpoint": "https://api.example.com/run",
"body": { "input": "..." }
},
"resObj": {
"status": 200,
"data": { "response": "..." }
},
"metadata": {
"model": "gpt-5",
"nodeType": "LLM",
"dependencies": ["SchemaRetriever", "Sanitizer"]
}
}
}
Lifecycle
The steps map is populated sequentially as the workflow executes:
- Initialization - The
steps object starts empty.
- Node Execution - An entry is created for each node as it begins running.
- Completion - Outputs and timing data are appended.
- Error Handling - Logs and status are updated;
branch reflects any failures.
Node Types Reference
| Node Type | Typical Fields | Description |
|---|
| Input / Start Node | user_query, metadata | Captures the initial user request or input values |
| API Node | body, statusCode, totalTime | Fetches external data from APIs, schemas, or databases |
| AI Node | reqObj, resObj, modelElapsedTime, inferenceTime | Records prompt and response data for auditability |
Loop Node Context
When a loop node executes, it creates its own context object tracking the loop’s progress and results.
Structure
{
"loopId": "string",
"startTime": "timestamp",
"iterationCount": "number",
"inputs": ["array of input values"],
"outputArray": ["array of iteration results"],
"totalCount": "number",
"childNodesExecuted": "number"
}
| Field | Type | Description |
|---|
loopId | String | Unique identifier for the loop node, matching the node ID in the flow |
startTime | Timestamp | When the loop started executing |
iterationCount | Number | Number of iterations completed |
inputs | Array | The original list of items the loop is processing |
outputArray | Array of Objects | Results from each iteration, in execution order |
totalCount | Number | Total number of items processed—equal to inputs.length |
childNodesExecuted | Number | Total child nodes that ran across all iterations |
The outputArray
Each item in outputArray represents one iteration’s result:
- Maintains the same order as the
inputs array.
- Each result is wrapped in an
output object.
- The structure of each
output depends on what the loop produces.
Example
Inputs: ["user1@example.com", "user2@example.com"]
{
"loopId": "Add2DB_0",
"startTime": "2025-11-12T09:23:05.306Z",
"iterationCount": 2,
"inputs": ["user1@example.com", "user2@example.com"],
"outputArray": [
{
"output": {
"success": "user1@example.com added to the Employee Database",
"processId": "cfp-d687dc0a-4608-4f41-a4f3-68a691d9dce6"
}
},
{
"output": {
"success": "user2@example.com added to the Employee Database",
"processId": "cfp-5fb1718e-5962-4f43-b1af-b52bda936b09"
}
}
],
"totalCount": 2,
"childNodesExecuted": 10
}
Accessing Loop Data
Inside the loop – Use special context variables scoped to the current iteration:
| Variable | Description | Example |
|---|
{{context.currentItem}} | The item currently being processed | user1@example.com in the first iteration |
{{context.currentIndex}} | Zero-based index of the current item | 0 for the first iteration |
{{context.currentOutput[x]}} | Output from a previous iteration | {{context.currentOutput[0]}} returns the first iteration’s output |
Outside the loop - Access full results using the loop node’s ID:
| Variable | Description |
|---|
{{context.steps.Loop0001.output}} | Complete array of all iteration results |
{{context.steps.Loop0001.output[x]}} | A specific iteration’s result |
Using the Context Object
Cross-Node Referencing
Nodes reference each other’s data through context interpolation using the {{ }} syntax. Values are resolved at runtime—no code required.
"steps": {
"SchemaRetriever": {
"output": { "schema": [ ... ] }
},
"QueryGenerator": {
"input": {
"schema": "{{steps.SchemaRetriever.output.schema}}"
}
}
}
Reference Patterns
{{context.appId}}
{{context.steps.QueryGenerator.output.sql_query}}
{{context.schema[0].column_name}}
context refers to the full Context Object.
steps provides scoped access to node-level data.
- References work anywhere: input fields, API parameters, LLM prompts, and conditions.
Evaluation Behavior
- Lazy resolution - Values are resolved immediately before each node executes.
- Missing keys - Resolve to
null (or an empty string in string contexts).
- Circular references - Automatically detected and blocked.
Typing {{ in any field that supports context variables displays a dropdown of all available variables, grouped by node—including environment variables defined at the workflow level.
Extending with Script Nodes
Script Nodes let you extend the Context Object programmatically during execution. This is useful for storing computed values, passing control variables across nodes, and persisting contextual data for downstream use.
JavaScript
// Add a simple key-value pair
context.newKey = "Hello World";
// Store structured data
context.customData = {
runId: context.cfProcessId,
stage: "validation",
timestamp: new Date().toISOString()
};
// Access it in later nodes
console.log(context.customData.stage);
Python
# Add or modify keys in the context dictionary
context['newKey'] = "Hello World"
# Store complex objects
context['customData'] = {
"runId": context.get('cfProcessId'),
"stage": "validation",
"timestamp": datetime.now().isoformat()
}
# Retrieve later
print(context['customData']['stage'])
Guidelines
- Use camelCase naming (
customerInfo, retryCounter, tempResults)
- Do not override reserved keys:
steps, branch, status, dbquery
- Keep data lightweight—avoid storing large arrays or raw API responses
- All keys added to the context are accessible downstream via
{{context.<key>}}
Best Practices
- Use consistent node naming for traceability (e.g.,
QueryGenerator, DataCleaner).
- Mask sensitive data before writing it to the context.
- Prefer declarative references (
{{ ... }}) for readability whenever possible.
- Use Script Nodes only when dynamic or computed context manipulation is required.