Context Object - Structural Reference Guide¶
The Context Object is the central runtime state container for any workflow execution within the platform.
It captures everything about a run - from inputs, intermediate data, and node-level status to final outputs and metadata required for debugging, visualization, or rehydration of the session.
Every execution instance (or run) has a single Context Object that's dynamically updated as the workflow progresses.
Top-Level Structure¶
At the highest level, the Context Object includes the following key categories:
| Category | Key Examples | Description |
| Run Metadata | startDate, status, flowType, appId, versionId, cfProcessId | Identifiers and timestamps for the workflow instance |
| Execution State | steps, branch, activeSteps, status | Information on each node’s progress and outcome |
| Environment & Config | env, agentTimeout, asyncExecDetails | Defines the runtime or environment parameters |
The steps Object¶
The steps object is the most critical part of the Context.
It’s a map (or dictionary) that holds the state of each node in the workflow, indexed by its unique node name or ID.
Each node’s entry in steps represents its execution context, including:
| Section | Purpose |
| input | The data received by this node at the time of execution (usually produced by previous nodes or user input). |
| output | The result or payload produced by the node. Can include model outputs, processed data, or API responses. |
| statusCode / isSuccessful | Indicates whether execution succeeded, failed, or was skipped. |
| logs | Optional log text or debug messages generated by the node. |
| executionTime, totalTime, pausedAt, resumedAt | Node-level timing data to measure performance or latency. |
| reqObj / resObj | For nodes that invoke models, these fields capture the raw request and response envelopes. |
| metadata | Optional node-specific information such as schema references, task IDs, or external job handles. |
Example Generalized 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"]
}
}
}
How the steps Map Evolves¶
The platform populates the steps map sequentially as the workflow executes:
- Initialization: The steps object starts empty.
- Node Execution: Entry created for each running node.
- Completion: Outputs and timing appended.
- Error Handling: Logs and status updated, branch reflects failures.
Common Node Types and Expected Fields¶
| Node Type | Typical Fields | Description |
| Input Node / Start Node | user_query, metadata | Captures the initial user request or input values |
| API Node | body, statusCode, totalTime | Fetches external data (schemas, APIs, databases) |
| AI Node | reqObj, resObj, modelElapsedTime, inferenceTime | Records prompt/response data for auditability |
Special Mention: Loop Node Context Object¶
When a loop node executes in the flow, it creates a context object that tracks the loop's progress and results. This context object is accessible throughout the flow and contains the following information:
Structure Overview¶
{
"loopId": "string",
"startTime": "timestamp",
"iterationCount": "number",
"inputs": ["array of input values"],
"outputArray": ["array of iteration results"],
"totalCount": "number",
"childNodesExecuted": "number"
}
Field Descriptions¶
| Field | Type | Description |
| loopId | String | Unique identifier for the loop node (matches the node ID in your flow) |
| startTime | Timestamp | When the loop started executing |
| iterationCount | Number | Current number of iterations completed |
| inputs | Array | The original list of items the loop is processing |
| outputArray | Array of Objects | Results from each iteration, stored in order of execution |
| totalCount | Number | Total number of items processed (same as the length of inputs) |
| childNodesExecuted | Number | Total count of child nodes that ran across all iterations |
Understanding the outputArray¶
Each item in the outputArray represents one iteration's result:
- The array maintains the same order as the
inputsarray - Each iteration's result is wrapped in an
outputobject - The structure of each
outputdepends on what your loop produces
Example¶
If your loop processes a list of email addresses to add them to a database:
Inputs: ["user1@example.com", "user2@example.com"]
Context Object:
{
"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
}
How to Use This Context¶
The loop context provides different ways to access data depending on whether you're working inside or outside the loop node.
Inside the Loop Node¶
When configuring nodes that run within the loop, use these special context variables:
| Variable | Description | Example |
{{context.currentItem}}
|
The item currently being processed in this iteration | If processing ["user1@example.com", "user2@example.com"], this would be "user1@example.com" in the first iteration
|
{{context.currentIndex}}
|
The zero-based index of the current item | 0 for the first iteration, 1 for the second, etc.
|
{{context.currentOutput[x]}}
|
Access a specific value from the output array of previous iterations | {{context.currentOutput[0]}} would give you the output from the first iteration
|
Outside the Loop Node¶
After the loop completes, access the full results using the loop node's ID:
| Variable | Description | Example |
{{context.steps.Loop0001.output}}
|
The complete array of all iteration results | Access all outputs from a loop node with ID "Loop0001" |
{{context.steps.Loop0001.output[x]}}
|
A specific iteration's result | {{context.steps.Loop0001.output[0]}} gets the output entry for the first iteration from the loop’s output array
|
Quick Reference¶
Inside Loop: Use currentItem, currentIndex, currentOutput[x]
Outside Loop: Use context.steps.LoopNodeId.output[x],context.steps.LoopNodeId.output
Using the Context object¶
Cross-Node Referencing¶
Nodes can reference each other’s data declaratively through context interpolation, using the double-curly ({{ }}) syntax.
Example:
"steps": {
"SchemaRetriever": {
"output": { "schema": [ ... ] }
},
"QueryGenerator": {
"input": {
"schema": "{{steps.SchemaRetriever.output.schema}}"
}
}
}
When the workflow runs, the expression inside {{ ... }} is automatically resolved at runtime using the Context Object.
This declarative referencing allows you to bind data from previous nodes without writing code.
Supported Reference Patterns¶
You can reference any accessible value from the Context Object:
{{context.appId}}
{{context.steps.QueryGenerator.output.sql_query}}
{{context.schema[0].column_name}}
- context refers to the full context object.
- Steps obj provides scoped access to node data.
- References can be used anywhere - in input fields, API node parameters, LLM prompts, or conditions.
Evaluation Behavior¶
- Interpolation is lazy - values are resolved right before node execution.
- If a referenced key doesn’t exist, the expression resolves to null (or an empty string in string contexts).
- Circular references are automatically detected and blocked.
Extending the Context Object with Script Nodes¶
In addition to declarative referencing, developers can extend the Context Object dynamically during execution using Script Nodes.
This is useful for:
- Storing computed or intermediate values.
- Passing control variables across nodes.
- Logging or persisting contextual data for downstream use.
JavaScript Example¶
// 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 Example¶
# 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).
- Avoid overriding system-reserved keys (steps, branch, status, dbquery).
- Keep data lightweight - avoid large arrays or raw API responses.
- Everything added to the context object is accessible in later nodes through {{context.<key>}} references.
Best Practices¶
- Use consistent node naming for traceability (QueryGenerator, DataCleaner).
- Mask sensitive data before writing to the context.
- Use declarative references ({{ ... }}) for readability whenever possible.
- Use Script Nodes only when dynamic or computed context manipulation is required.