Skip to main content

Eval Step

The Eval step runs JavaScript inside the flow. You map values in as params, write code, and the value the code evaluates to becomes the step’s result. The runtime is small and embedded — not Node.js. There is no module system, no console, no timers and no network access. Everything the code works with must arrive through params.
Reach for Eval when a transformation needs logic. For a straight reshape of data you already have, the Map step is simpler and cannot fail at runtime.

The contract

Three rules cover nearly every mistake people make with this step:
  1. Each params key becomes a global variable. A param named tickets is used in the code as tickets, not params.tickets and not input.tickets.
  2. The result is the value of the last expression. There is no output variable to assign.
  3. You cannot return at the top level. A bare return is a syntax error. To use return, wrap the code in a function and call it immediately.

Configuration

The editor has a General tab (step name and ID) and a Code tab holding four sub-tabs: Run Test executes the code against the Lookup data using the same engine the flow uses.
string
required
The JavaScript to evaluate.
JSON object
Variables to expose to the code. {"tickets": "$.GET_TICKETS.data", "threshold": 20} gives the code a tickets variable and a threshold variable. Values may be literals or JSONPath.

Examples

Every example below was run through the engine the step uses; the outputs are what it returned.

Reshape a list

Params
Code
With tickets = [{"ref":"T-104","team":"support","minutes":45,"resolved":true}, {"ref":"T-105","team":"support","minutes":12,"resolved":false}, {"ref":"T-106","team":"onboarding","minutes":30,"resolved":true}]:

Aggregate with a wrapped function

Statements need a function around them, and the call must be the last expression.

Guard against a param that resolved to nothing

A JSONPath that matches nothing resolves to an empty array — not null and not undefined — so check for that shape before working on it. Params
Code
With no tickets: { "status": "no_data", "slow": [] }. With two tickets of 45 and 12 minutes: { "status": "ok", "slow": ["T-104"] }.

Dates and modern syntax

const, let, arrow functions, template literals, classes and spread all work. Params
Code
With created_at = "2026-08-27T09:15:00Z" and name = " Dana Reyes ":

What the runtime does not have

The following are absent. Code that uses them fails at run time, and the failing step ends the run.
  • require and import. There are no libraries to load — no Lodash, no Moment, no Math.js, no crypto. require('lodash') throws ReferenceError: require is not defined.
  • console. console.log throws ReferenceError: console is not defined. To inspect a value, make it part of the result and read it in the run’s logs.
  • Timers. setTimeout and setInterval are undefined. For a wait, use the Delay step.
  • Network and file access. For an outbound call, use the HTTP Request step.
  • An event loop. async functions and Promises never settle: an async function call returns an unsettled Promise, which is stored as {}. Write ordinary synchronous code.
  • A time limit. Nothing interrupts running code, so an unbounded loop hangs the run until it is cancelled. Bound every loop yourself.
Built-ins that are present include JSON, Math, Date, RegExp, Object, Array and String, with the common newer methods such as Object.entries and Array.prototype.includes. The editor summarises the level of support as core ES5 plus part of ES6.

Referencing the result

The value is stored flat under the step’s ID. If the step ID is eval_1 and the code returned an object:
If the code returned an array or a single value, $.eval_1 is that value. There is no .output or .result wrapper.

Troubleshooting

The code has a return outside a function. Wrap the body in (function () { … })().
Either the variable is a params key that was never added on the Params sub-tab, or it is something the runtime does not provide — require, console, setTimeout, fetch, process.
An async function was called, or a Promise was the last expression. Neither ever settles here. Rewrite the code synchronously.
The JSONPath in Mapped Params matched nothing. Check the path against the Lookup tab, remembering that a step’s data is keyed by its step ID.
A loop is not terminating. Nothing times the code out, so the guard has to be in the code.
Editing a flow changes its draft. Test there, then Publish to make the change take effect.

Next Steps

Map Step

Reshape data without writing code

Variable Mapping

JSONPath reference for Mapped Params

Condition Step

Branch on what the code returned

Functions Step

Built-in operations for common tasks