Pular para o conteúdo principal

JavaScript Node

LLMs are great at language and unreliable at arithmetic. Ask one to sum 47 invoice line items and it might round creatively, skip a row, or paraphrase your numbers. And every retry costs you another LLM call.

The JavaScript node fixes that. You write a few lines of code in the agent builder; the workflow runs them on the server, exactly, every time. Sum the items, parse a date, reshape an API response — and pass the result to the next node. No LLM involved, so it's instant, free, and gives the same answer twice.

Find it in the agent builder: open the Flow canvas, drag a connection into empty space, and pick JavaScript from the node menu.

Writing the code

Your code is the body of a function. It receives the workflow's data and must return a value:

const items = nodes.fetchOrders.response.body.items || [];
const total = items.reduce((sum, item) => sum + item.price, 0);
return { total, count: items.length, formatted: `R$ ${total.toFixed(2)}` };

Three rules:

  1. Always return something. The returned value is the node's output. Without a return, the node runs and produces nothing.
  2. Return plain data — objects, arrays, strings, numbers, booleans. Anything that fits in JSON. Functions and circular structures fail.
  3. Keep it synchronous. There's no await, no fetch, no timers. To call an API, put a webhook node before this one and read its response here.

What your code can read

The function receives one object with everything the workflow knows — the same data Handlebars templates see:

NameWhat's in it
varsWorkflow variables: output from earlier nodes and state fields
input.textThe message the user sent to start this run
nodesEarlier node results by node id, e.g. nodes.fetchOrders.response.body
evaluationThe most recent decision node's scores and structured data
contextContext variables for this conversation
envEnvironment variables configured for the agent

So vars.customerName, input.text.toUpperCase(), and nodes.fetchOrders.response.status all work the way you'd expect.

Using the result

Set the node's Output variable (say, calc) and the returned value becomes available everywhere downstream:

  • In templates: an instructions node can write The total is {{calc.formatted}}
  • In conditions: route the flow with a transition like vars → calc.count → greater than → 0 — including on the JavaScript node's own transitions, so you can branch on what the code just computed
  • From other code: another JavaScript node can read nodes.<this-node-id>.result

A common pattern — validate, then branch:

const numbers = input.text.split(',').map((n) => parseFloat(n.trim())).filter((n) => !isNaN(n));
const sum = numbers.reduce((a, b) => a + b, 0);
return { sum, count: numbers.length, valid: numbers.length > 0 };

Give the node two transitions: one where calc.valid equals true goes to the answer, one where it equals false asks the user to try again.

Limits

The code runs in a sandbox with hard limits, so a typo can't take your agent down:

LimitValue
Time1 second by default; configurable up to 10 seconds
Memory64 MB
Returned value256 KB serialized
Network, files, importsNone — the sandbox has no fetch, no filesystem, no require

console.log works: whatever you log shows up in the run's execution logs, which makes debugging easy.

When things go wrong

If the code throws, times out, or returns something that doesn't fit in JSON, the node records the error and the workflow keeps going through its transitions — the run doesn't crash. No output variable is written, so guard downstream conditions with an exists check when your code can fail.

Open the agent's Logs tab to see what happened: each JavaScript step shows its returned value, console output, duration, and the error message when it failed.

When to use it (and when not)

Use a JavaScript node for anything with a single correct answer: math, counting, parsing, date and currency formatting, reshaping an API response, building a string from parts.

Don't use it for:

  • Understanding language — classifying intent or writing a reply is what decision and instruction nodes are for
  • Calling external systems — that's the webhook node; transform its response here
  • Storing a simple flag — a state node does that without any code