Skip to main content

Variable Mapping

Every step in a flow is configured with a JSON object. Before the step runs, that object is resolved: any string beginning with $. is read as a JSONPath expression and replaced by the value it finds in the run’s data. Everything else is copied through unchanged. That resolver is variable mapping. It is the same code everywhere it appears, so what you learn here applies to every step, not just the Map step.
The engine is jsonpath-plus behind a thin wrapper. The wrapper adds exactly one thing: | concatenation. There is no expression language, no transform functions and no filters beyond what JSONPath itself provides.

What is available to read

The run’s data is a flat object with these keys: A step’s result is stored flat under its own ID. If a step’s ID is GET_ORDER, its result is at $.GET_ORDER, and a field inside it at $.GET_ORDER.data.total. There is no .output or .result wrapper.
Only finished steps are readable. Branches that fan out from the same step run at the same time, so one of them cannot read another. A reference to a step that has not finished resolves to [], not an error.

Where mapping is applied


The two forms

A query

A string that starts with $. and contains no | is a JSONPath query. The value it finds is returned with its type intact.
Numbers stay numbers, booleans stay booleans, objects and arrays keep their shape. See JSONPath for everything a query can express.

A concatenation

A string containing | is split on the | characters. Segments starting with $. are looked up and turned into text; every other segment is emitted literally; the pieces are joined.
The result is always a string. See Concatenation.
| is a delimiter, never an operator. $.order.status|pending does not fall back to "pending" — it produces "shippedpending". There is no | default(…), no | upper, and no chaining of any kind.

Path shapes

The thing you write a mapping into does not have to be a string.
Every value is resolved, to any depth. Keys are preserved.
A null in a mapping resolves to {}, not null. Omit the key instead.

The two failure modes

These are the only two ways a mapping surprises you, and both are silent.

A path that matches nothing

It resolves to [], and the key stays in the output.
against {"node": {"name": "Alice"}}:
The key is not removed, and the value is not null or undefined. A downstream step that checks for a missing key will not find one — test with Array.isArray(x) && x.length === 0, or add a trailing | to get "" instead.

A path that matches many where you expected one

One hit returns the value itself. Zero or several hits return an array. The shape of the result therefore depends on the data, not on the expression. With three items priced 149.99, 150.00 and 9.99: The same expression returns a list, a bare string, or an empty array purely according to how many rows matched. Anything reading that value must cope with all three, so prefer an Eval step when the count matters.

Testing a mapping

The Map and Eval step editors each have a Run Test button that resolves the mapping against sample data using the same engine the flow uses, so what you see is what the step will produce.
Editing a flow changes its draft. A change only affects the live flow once you Publish it.

Next steps

JSONPath

Every selector and filter that works, with its real output

Concatenation

Building strings with |, and what it cannot do

Examples

Worked mappings, run end to end

Map Step

The step whose entire job is a mapping