Mapping Reference
This page lists the exact rules for mappings: how a step’s fields get their values. For a walkthrough with a real workflow, start with Data and mappings.
Value modes
| In the editor | Mode button tooltip | valueType in workflow JSON |
Produces |
|---|---|---|---|
| Value | Immediate mode | immediate |
The literal value: text, number, boolean, object, or list. |
| Reference | Reference mode | reference |
The value at a path in the run, with its original type. |
| Template | Template mode | template |
Text rendered from a template. Always a string. |
| Build | Composite mode | composite |
An object or list whose fields are themselves mappings. |
In workflow JSON (through the API or MCP), each mapped field is an object with valueType and value:
{ "valueType": "immediate", "value": "PurchaseOrder" }
{ "valueType": "reference", "value": "data.body.supplier", "default": "Unknown supplier" }
{ "valueType": "template", "value": "New order {{ data.reference }} from {{ data.supplier }}" }
{ "valueType": "composite", "value": { "sku": { "valueType": "reference", "value": "item.sku" },
"source": { "valueType": "immediate", "value": "docs" } } }
A reference can also carry a type hint (see Type hints). A composite value can be an object or a list, and composites can be nested.
Reference roots
A reference path starts with one of seven roots. Any other root is rejected when you save (E126).
| Root | Holds | Available |
|---|---|---|
data |
The run’s input. Inside a Split, the current item instead. | Everywhere |
variables |
Workflow variables, built-in variables, and values passed into a loop | Everywhere |
workflow |
The run’s original input, as workflow.inputs.data.* and workflow.inputs.variables.* |
Everywhere, including inside loops |
steps |
Outputs of steps that ran earlier, as steps.<id>.outputs.*, and the error being handled, as steps.__error.* |
After the step has run, in the same graph |
iteration |
iteration.index, iteration.indices, iteration.item |
Inside Split and While steps, and in a While step’s condition |
loop |
loop.index and loop.outputs.* (the previous pass’s result) |
In a While step’s condition and inside While and Split steps |
item |
The current element | In a Filter step’s condition and inside a Split step |
Scope rules
- The run’s original input is under
workflow.inputs.data, for exampleworkflow.inputs.data.customer.name. - Inside a Split,
item,data, anditeration.itemall refer to the current element, anditeration.indexcounts from 0. - Inside a While step,
loop.indexanditeration.indexboth give the pass number, counting from 0. - Workflow variables are available inside a Split. Results of steps outside the Split are not: pass them in through the Split’s
variablessetting and read them asvariables.<name>. While steps have the samevariablessetting. - A step reads only steps that run before it.
Built-in variables
| Variable | Value |
|---|---|
variables._workflow_id |
The workflow’s ID |
variables._instance_id |
The run’s ID |
variables._tenant_id |
The tenant’s ID |
They work in references and templates.
Path syntax
| Path | Input | Result |
|---|---|---|
data.customer.name |
{"customer": {"name": "Northwind Components"}} |
"Northwind Components" |
data.customer.address.city |
nested object | "Hamburg" |
data.meta["a.b"] |
{"meta": {"a.b": "dotted key value"}} |
"dotted key value" |
data["customer"]["name"] |
quoted segments | "Northwind Components" |
data.items[0].sku |
a list of three items | the first item’s sku |
data.items[-1].sku |
the same list | the last item’s sku |
data.items |
the same list | the whole list |
steps["echo"].outputs["status"] |
quoted step ID and field | the field’s value |
data.customer.nickname |
field not present | null |
data.items[9].sku |
index past the end | null |
Use quoted brackets for keys that contain dots, spaces, or other special characters. A missing field or index resolves to null; it does not fail the step. An unterminated bracket such as data.items[abc is rejected when you save (E011).
Fallback values
default on a reference (Fallback value in the editor) is used when the path resolves to null or is missing, and when a type hint cannot convert the value.
| Reference | Input | Result |
|---|---|---|
data.customer.nickname, default "n/a" |
no nickname |
"n/a" |
data.nothing, type integer, default 0 |
null |
0 |
data.qty, type integer, default 1 |
"twelve" |
1 |
Type hints
A reference can carry a type to convert values from loosely typed sources, such as text from an HTTP response or an email.
type |
Input | Result |
|---|---|---|
integer |
"12" |
12 |
number |
"19.90" |
19.9 |
boolean |
"true" |
true |
object |
"{\"sku\": \"NW-118\", \"lines\": 2}" |
{"sku": "NW-118", "lines": 2} |
string |
1250.75 |
"1250.75" |
integer |
null |
null |
integer |
"twelve" |
The step fails: value “twelve” cannot be coerced to integer |
Valid hints are string, integer, number, boolean, object, array, and file. json still works but is deprecated (W093). Any other name is rejected when the workflow is saved.
Templates
Templates use the Jinja syntax (Runtara renders them with MiniJinja). They read data, variables, and steps the same way references do, and always produce text.
| Template | Result |
|---|---|
Order for {{ data.name }} in {{ variables.region }} |
Order for Northwind Components in EU |
{{ data.amount }} |
"1250.75" (text) |
{% if data.amount > 1000 %}needs approval{% else %}auto{% endif %} |
needs approval |
{% for t in data.tags %}{{ t }}{% if not loop.last %}, {% endif %}{% endfor %} |
urgent, eu, q4 |
{{ variables._instance_id }} |
the run ID |
Filters
Common filters, shown with name = Northwind Components, tags = ["urgent", "eu", "q4"], and amount = 1250.75:
| Filter | Example | Result |
|---|---|---|
upper |
{{ data.name | upper }} |
NORTHWIND COMPONENTS |
lower |
{{ data.name | lower }} |
northwind components |
title |
{{ "hello world" | title }} |
Hello World |
trim |
{{ " padded " | trim }} |
padded |
replace |
{{ data.name | replace("Components", "GmbH") }} |
Northwind GmbH |
default |
{{ data.nothing | default("none") }} |
none |
join |
{{ data.tags | join(" / ") }} |
urgent / eu / q4 |
length |
{{ data.tags | length }} |
3 |
first |
{{ data.tags | first }} |
urgent |
round |
{{ data.amount | round(1) }} |
1250.8 |
tojson |
{{ data.tags | tojson }} |
["urgent","eu","q4"] |
Missing values in templates
- A missing field renders as empty text:
[{{ data.nope }}]gives[]. Saving warns about it (W052). - Reading a field of a value that does not exist fails the run with Template render error: undefined value. For example,
{{ input.name }}fails because there is noinput. - Template paths are not checked against the workflow’s roots when you save, so check templates with a test run.
Build (composite) values
- A composite object’s fields, and a composite list’s items, can each be a value, a reference (with type and fallback), a template, or another composite.
- References written inside a Value (an
immediatemapping) are resolved only in Agent and AI Agent step inputs. That is how a Database query condition reads run data: in a condition such asname = data.body.supplier, a reference toname(not a workflow root) is read as the table column, anddata.body.supplieris read from the run. In any other step, a reference inside a Value is passed on as literal JSON, and saving warns (W090).
Step output shapes
What steps.<id>.outputs holds, by step:
| Step | outputs |
|---|---|
| Agent: Utils, Calculate | The number itself, for example 84.0 |
| Agent: Utils, Return Input | The value given to it |
| Agent: Transform, Array Length | { "length": 3, "is_array": true } |
| Agent: Object Model, Query Instances | { "success": true, "instances": [...], "total_count": 2, "error": null } |
| Split | A list with one entry per item: that iteration’s Finish outputs |
| Filter | { "count": 2, "items": [...] } |
| While | { "iterations": 3, "outputs": { ...last pass's Finish outputs } } |
| Start Workflow | The child workflow’s Finish outputs |
| Wait for Signal | The answer’s fields, for example decision |
For any agent capability, the Output section of the step panel shows its declared output.
Error handler data
On a path reached through an error handler (an onError route), steps.__error holds the error:
{
"code": "HTTP_5XX",
"message": "HTTP 502: {\"error\":\"Upstream request failed\"}",
"category": "transient",
"severity": "warning",
"retryable": true,
"stepId": "call",
"agentId": "http",
"capabilityId": "http-request",
"attributes": { "status_code": "502", "url": "...", "body": "..." }
}
error.* and __error.* still resolve to the same data but are deprecated (W053).
HTTP trigger input
A run started by an HTTP trigger receives the request as its input:
| Path | Value |
|---|---|
data.body |
The parsed request body |
data.method |
"POST", "GET", and so on |
data.path |
The request path |
data.query |
The raw query string, for example "runLabel=ORD-5521" |
data.uri |
Path and query |
data.content_type |
For example "application/json" |
A runLabel query parameter on the trigger URL sets the run’s label.
Validation messages
Saving a workflow checks its mappings. Errors (E) block the save; warnings (W) do not.
| Code | Meaning | Example that triggers it |
|---|---|---|
| E010 | The referenced step does not exist, or is outside this loop | steps.nope.outputs.x |
| E011 | Invalid reference path | data.items[abc, or workflow.inputs.customer.name |
| E012 | The referenced step has not run yet at this point | A step reading a later step’s output |
| E013, E053 | Unknown variable | variables.nope |
| E025 | A condition is not shaped as a condition expression | A condition argument written as a bare string |
| E026 | A step needs a connection but has none | An Object Model step without a connection |
| E051 | The field is not in the workflow’s input fields | data.nope |
| E052 | data.* is used but the workflow defines no input fields |
data.name with no Input settings |
| E126 | Unknown reference root | input.name |
| E127 | The root is not available here | iteration.index outside a loop |
| W051 | The path goes inside an object whose fields are not declared, so it cannot be checked | data.customer.name when customer is a plain object |
| W052 | A template reads a field that is not declared | {{ data.nope }} |
| W053 | Deprecated spelling of the error data | error.message |
| W090 | A reference inside a Value is passed on literally | Outside Agent and AI Agent steps |
| W093 | Deprecated spelling | The json type hint |
The message for each code names the step and the path, and often suggests the closest valid name. Validation errors lists every code, including those outside mappings.
Full specification
The server publishes the complete workflow language schema, including every mapping shape, at /api/runtime/specs/dsl on your Runtara server.