Run custom JavaScript within your workflows. The Code node executes your script in a sandboxed Deno runtime — use it to transform data between nodes, compute values, or add custom logic without leaving the canvas.

Writing code

The code editor sits directly on the node body; use the expand button for a larger view. JavaScript is the only supported language.

  • Connected inputs are available as the inputs object and directly by name: a value wired to a handle named data1 is readable as data1 or inputs.data1. Every declared or wired identifier exists on every run; when an upstream node produced no value, its direct binding is null. Do not wrap wired inputs in typeof ... !== "undefined" guards. Handle names that are not valid identifiers stay reachable as inputs["..."].
  • Plain workflow environment settings are available through the read-only env object, for example env.API_HOST. This is not the process/OS environment and never contains resolved tenant secrets.
  • End the script with return to pass a value downstream — the returned value becomes the result output. A script that returns nothing passes its inputs through unchanged.
  • console.log, console.warn, console.info, and console.error output is captured into the logs output.
  • console.warn is additionally surfaced as a run warning. At most 50 warning lines are retained, each capped at 1 KiB after tenant-secret redaction. A returned warnings list is treated the same way.
JAVASCRIPT
// A connection wired to the `records` handle
const items = records || [];
return {
  count: items.length,
  names: items.map((item) => item.name.toUpperCase()),
  source: env.SOURCE_NAME,
};

Note: {{ }} templates are not resolved inside the code field — braces there are code, not templates. Wire dynamic values in as inputs instead.

Inputs

Wire any output into the node — each connection becomes a named input the script can read. There is no fixed input schema. An optional upstream that did not produce a value still has a direct binding whose value is null.

A dedicated chunks input (collapsed by default) accepts a live stream and switches the node into streaming mode (see below).

Outputs

Output Description
result The value returned by the script
logs Console output captured during execution
metrics Execution metrics such as duration
emit Values emitted per chunk in streaming mode

logs, metrics, and emit are collapsed by default — expand them on the node to wire them.

Declared outputs — the Outputs section in the sidebar declares typed output ports over result: extract values by path, attach a schema, and pick the mismatch policy. Strict fails the node when the value does not match.

Node settings

Setting Description Default
Memory Limit (MB) Maximum memory usage (1–256) 32
CPU Quota CPU allocation, 1.0 = one core (0.1–2.0) 1.0
Parallel executions How many executions of this node may run at the same time in this workflow (1–10). It does not limit workflow runs 1
Allow Network Access Permit outbound requests to the allowlisted hosts off
Network Allowlist Comma-separated hosts (e.g. api.example.com, api.example.com:443) the code may reach when network access is on; empty means no egress —
Capture Logs Persist console output with each run on
Capture Stdout Include stdout in the logs output on

The gear button ("Execution & runtime") in the sidebar header opens settings every node shares:

  • On Failure — what happens when this node fails: Stop (default), Continue, or Continue (pass error output).
  • Run even if upstream failed — execute this node even when upstream nodes failed (off by default).
  • Timeout (ms) — node-level timeout; defaults to 60000 for this node.
  • Retry on Failure — retry the node when it fails (off by default), with max attempts, retry delay, and linear or exponential backoff.

Streaming mode

Wire a live stream into the chunks input and the script runs once per chunk instead of once per run. Three inputs are available on each run:

  • chunk — the current chunk
  • state — the value carried over from the previous chunk (null on the first)
  • index — the 0-based chunk index

The script's return value controls the stream:

  • { emit: value } — send value out the emit port; include a state key to carry a value to the next chunk
  • { state: value } — carry state and emit nothing
  • { done: true } — stop the stream
  • anything else — skip the chunk

When the stream ends, result carries the final state. A script error stops the stream and fails the node.

Built-in helpers

Every script has a rollout helper object for producing the canonical data shapes other nodes expect:

  • rollout.message(role, text) — a chat message
  • rollout.messageList(value) — normalize an array (or single value) into a message list
  • rollout.attachmentRef(descriptor) — an attachment reference
  • rollout.validate(shape, value) — structural check against a shape; returns { valid, errors }
  • rollout.example(shape) and rollout.shapes — bundled examples and the available shape names

Security and limits

  • Code runs in a locked-down sandbox with no file system or process-environment access. The read-only env object contains only authored plain workflow settings. On the managed cloud, each execution additionally runs in its own isolated container.
  • Network access is denied by default. On self-hosted deployments, enabling Allow Network Access grants egress only to the allowlisted hosts — never everything — and private, loopback, and cloud-metadata hosts are always blocked. On the managed cloud the sandbox has no outbound network regardless of this setting; use the HTTP request node for HTTP calls.
  • Each script execution is capped at 10 seconds (per chunk in streaming mode).
  • Scripts are limited to 50,000 characters.
  • Patterns such as eval(...), Function(...), require(...), and Node.js globals like process are rejected before execution.
  • Code executions are rate limited per team (60 per minute by default).

Troubleshooting

Execution timeout

  • A single script execution is capped at 10 seconds — reduce the work per run or split it across nodes
  • Raising Timeout (ms) extends the node's overall budget (relevant in streaming mode) but not the per-script cap

Missing output

  • result carries the script's return value — make sure the script ends with return
  • Check declared output paths for typos

Security policy violation

  • Remove blocked patterns (eval, Function, require, process, global)
  • The script may have attempted file, environment, or non-allowlisted network access

Rate limited

  • Too many code executions in a short window — space out runs or enable Retry on Failure