input_data dictionary, anything you print() (or console.log()) is captured as console_output, and every executor doubles as an AI agent tool when connected to an agent’s tools input.
Choosing an executor
Rule of thumb: Monty Executor for AI-generated or untrusted code (its limits are actually enforced), Python Executor for your own quick transforms, JavaScript/TypeScript Executor when the logic is more natural in JS or needs npm-ecosystem idioms.
Python Executor
Runs Python directly in the backend process. Assign your result to a variable namedoutput — that value becomes the node’s output.
Parameters
code
required
Python source. Must assign to
output to emit a value.number
default:"30"
Accepted and validated (1-600 seconds) but not enforced — a hanging script blocks the backend. Use Monty Executor when you need an enforced limit.
Pre-injected names
A fixed set of names is available in the namespace without importing:math— mathematical functionsjson— JSON parsingdatetime— date/time handlingre— regular expressionsrandom— random number generationCounter,defaultdict— collections helpers
math.sqrt(4) or json.loads(raw).
Imports are blocked
import statements are not available — the sandboxed builtins have no __import__, so import requests fails with an error explaining that imports are not allowed and listing the pre-injected names. The fix: use the pre-injected modules directly, or reach for the Process Manager node when you genuinely need another module or an external program.
Output
print() output captured before the failure is preserved in the error.
Example: data processing
Monty Executor
A hard-sandboxed alternative that runs code through Monty, a Python subset implemented in Rust. It is deny-by-default — no filesystem, no network, no host access — unless you grant specific capabilities, and its time and memory limits are enforced by the interpreter. Exposed to agents as thesandboxed_python tool.
Unlike the other executors, you do not assign to output: the program’s last expression becomes the output.
Parameters
code
required
Python (Monty subset) source. The last expression is returned as
output.number
default:"30"
Wall-clock limit in seconds (1-600), enforced
number
default:"256"
Memory limit in MB (16-2048), enforced
array
default:"[]"
Opt-in grants; empty means fully isolated.
http_get enables an SSRF-guarded http_get(url) function for public hosts; workspace_read / workspace_write mount the per-workflow workspace at /workspace (read-only / read-write).Language subset
Supported:def, closures, lambda, if/for/while, try/except, comprehensions, f-strings, async def/await, and import math, import json, import re.
Not supported: class, yield/generators, with, match, and imports of random, collections, or os. Unsupported features fail with a clear error suggesting the Python Executor instead.
Output
Example
output.
JavaScript Executor
Runs JavaScript on a persistent Node.js executor server that the backend starts alongside itself (defaulthttp://localhost:3020) — no per-call process spawn. Assign your result to output; console.log and friends are captured as console_output.
Parameters
code
required
JavaScript source. Must assign to
output.number
default:"30"
Script timeout in seconds (1-600), forwarded to the Node.js server as milliseconds
Output
Example
TypeScript Executor
Identical to the JavaScript Executor except the script runs throughtsx, so TypeScript type annotations parse without error. Same parameters (Code, Timeout), same output shape, same Node.js server. Types are erased at runtime — interfaces and type aliases are compile-time only, and the returned output is still plain JSON.
tsx surface verbatim as the node’s error message.
Passing data in and out
In:input_data. Each executor receives the outputs of its connected upstream nodes as a dictionary keyed by the source node’s id. Inspect it defensively (input_data.get(...) / input_data.x || fallback) since the exact keys depend on what is wired in.
Out: the return contract.
All four return the same payload shape:
{output, console_output}. Downstream nodes can reference the result with template variables ({{<node>.output}}).
Workspace access. The per-workflow workspace directory is available too: the Python Executor exposes a workspace_dir variable in the namespace; the JavaScript/TypeScript Executors inject it as input_data.workspace_dir; the Monty Executor sees the workspace at /workspace only when a workspace_read / workspace_write capability is granted.
JSON-only transport (JS/TS). The output value must survive JSON.stringify — functions, undefined, BigInt, and circular references are stripped or rejected.
Example: transform JSON from a webhook
Receive a webhook, reshape its payload, and respond:output to the caller via a template variable.
Tips
Related
Filesystem & Shell
Read and write workspace files, run shell commands
Webhooks
Trigger workflows over HTTP and respond
AI Agents
Give agents code execution as a tool
Schedulers & Triggers
Run transforms on a schedule