Reference · Tools

Code

Run custom JavaScript or Python code to transform, filter, or generate workflow data.

Action Core Nodes v1

The Code node runs JavaScript or Python scripts you write directly inside your workflow, giving you full programmatic control over data transformation, filtering, or generation. Use it when built-in nodes can't express the logic you need — for example, parsing a non-standard date format, computing a weighted score across items, or generating synthetic records. No external credentials are required.

Node type
Action
Parameters
9
Outputs
Output, Error
Credentials
None required

Code

Run custom JavaScript or Python code in a sandbox

Overview

The Code tool executes user-written JavaScript or Python code in a sandboxed environment. It supports two execution modes: “Run Once for All Items” processes the entire input array in a single invocation (the code receives all items via $input.all() in JavaScript or a pre-loaded items list in Python), and “Run Once for Each Item” runs the code once per input item (accessing $input.item in JavaScript or a pre-loaded item dict in Python). Code runs isolated from the workflow process and is terminated when it exceeds the configured timeout or memory limit. The code must return (JavaScript) or print JSON to stdout (Python) with the expected item structure. Timeout and memory limits are configurable.

Category: Core Nodes
Tool Name: code
Version: 1

Appearance: Icon: lucide-Code | Color: #2D2D2D

Node Type

Action — processes input items and produces output

Input / Output

DirectionPort(s)
InputInput
OutputOutput, Error

Credentials

This tool does not require any credentials.

Parameters

ParameterTypeRequiredDefaultDescription
ModeoptionsNorunOnceForAllItemsWhether to run the code once for all items or once per item.
Options: runOnceForAllItems, runOnceForEachItem
LanguageoptionsNojavaScriptThe programming language to write code in.
Options: javaScript, python
JavaScript Code (All Items)codeNostarter scriptJavaScript code that receives all items via $input.all() and must return an array of items. Also available: $input.first(), $input.last() and $input.length. (shown when Language is javaScript and Mode is runOnceForAllItems)
JavaScript Code (Each Item)codeNostarter scriptJavaScript code that receives the current item via $input.item and must return a single item. (shown when Language is javaScript and Mode is runOnceForEachItem)
Python Code (All Items)codeNostarter scriptPython code that receives all items as a pre-loaded items list. Must print JSON array to stdout. (shown when Language is python and Mode is runOnceForAllItems)
Python Code (Each Item)codeNostarter scriptPython code that receives the current item as a pre-loaded item dict. Must print JSON to stdout. (shown when Language is python and Mode is runOnceForEachItem)
Timeout (ms)numberNo30000Maximum execution time for the code in milliseconds.
Memory Limit (MB)numberNo128Maximum memory the code may use in megabytes.
Max ConcurrencynumberNo1Maximum number of items to process concurrently (each-item mode only). (shown when Mode is runOnceForEachItem)

Each code field opens pre-filled with a short runnable script for its language and mode, which you replace with your own. Only the field matching the current Language and Mode combination is used; the other three are ignored.

Output Data

Output items are whatever your code hands back. The input item JSON is not passed through on its own — if you want a field kept, your code has to return it — and binary data is not forwarded: your code receives each item’s JSON only, and each returned object becomes the JSON of one output item.

LanguageModeContract
JavaScriptRun Once for All Itemsreturn an array — each element becomes one output item
JavaScriptRun Once for Each Itemreturn a single item object, not an array
PythonRun Once for All Itemsprint(json.dumps([...])) — a JSON array, one element per output item
PythonRun Once for Each Itemprint(json.dumps({...})) — a single JSON object
  • Each returned element may be a full item ({ "json": { "id": 1 } }) or a bare object ({ "id": 1 }), which is wrapped as the item’s JSON for you. Anything that is not an object is rejected as an error.
  • Returning nothing at all produces no output items.
  • In Run Once for All Items mode the number of output items is whatever your code returns — it is not tied to the number of input items, which is what makes this node usable for filtering items out and for generating new ones.
  • Items that arrive already carrying an upstream error are not handed to your code; they are reported as errors according to the node’s error mode.
  • A run that exceeds Timeout (ms) or Memory Limit (MB) fails as an item error, as does code that throws, or Python that prints something other than valid JSON.

Reference the result downstream like any other item, e.g. {{ $json.total }}.

Usage Examples

  • Add a computed field to every item using JavaScript
  • Filter items with custom Python logic
  • Transform all items by restructuring their JSON
  • Generate new items from scratch using code
  • Deduplicate items using a custom comparison function

Example Configuration

JavaScript, all items — double a numeric field:

{
  "type": "code",
  "parameters": {
    "language": "javaScript",
    "mode": "runOnceForAllItems",
    "jsCodeAllItems": "const items = $input.all();\nreturn items.map(item => ({ json: { ...item.json, price: item.json.price * 2 } }));",
    "timeout": 30000,
    "memoryLimit": 128
  }
}

JavaScript, each item, with a concurrency limit:

{
  "type": "code",
  "parameters": {
    "language": "javaScript",
    "mode": "runOnceForEachItem",
    "jsCodeEachItem": "const item = $input.item;\nreturn { json: { id: item.json.id, slug: item.json.title.toLowerCase().replace(/ /g, '-') } };",
    "maxConcurrency": 4,
    "timeout": 10000,
    "memoryLimit": 128
  }
}

Python, all items — filter and transform:

{
  "type": "code",
  "parameters": {
    "language": "python",
    "mode": "runOnceForAllItems",
    "pythonCodeAllItems": "import json\nactive = [i for i in items if i['json'].get('active')]\nresult = [{'json': {'id': i['json']['id'], 'email': i['json']['email'].lower()}} for i in active]\nprint(json.dumps(result))",
    "timeout": 30000,
    "memoryLimit": 256
  }
}

Python, each item, with a concurrency limit:

{
  "type": "code",
  "parameters": {
    "language": "python",
    "mode": "runOnceForEachItem",
    "pythonCodeEachItem": "import json\nresult = {'json': {'name': item['json']['name'].strip(), 'score': round(item['json']['score'], 2)}}\nprint(json.dumps(result))",
    "maxConcurrency": 8,
    "timeout": 5000,
    "memoryLimit": 128
  }
}

Use runOnceForAllItems when you need to reduce the item set before passing downstream:

{
  "type": "code",
  "parameters": {
    "language": "javaScript",
    "mode": "runOnceForAllItems",
    "jsCodeAllItems": "return $input.all().filter(item => item.json.status === 'active');",
    "timeout": 30000,
    "memoryLimit": 128
  }
}

Use runOnceForEachItem when each item is processed independently with no cross-item logic:

{
  "type": "code",
  "parameters": {
    "language": "javaScript",
    "mode": "runOnceForEachItem",
    "jsCodeEachItem": "const item = $input.item;\nconst fullName = `${item.json.firstName} ${item.json.lastName}`;\nreturn { json: { ...item.json, fullName } };",
    "maxConcurrency": 10,
    "timeout": 30000,
    "memoryLimit": 128
  }
}

Use Python’s runOnceForAllItems for data aggregation across the full item set:

{
  "type": "code",
  "parameters": {
    "language": "python",
    "mode": "runOnceForAllItems",
    "pythonCodeAllItems": "import json\ntotal = sum(i['json']['amount'] for i in items)\nprint(json.dumps([{'json': {'total': total, 'count': len(items)}}]))",
    "timeout": 30000,
    "memoryLimit": 128
  }
}

Use Python’s runOnceForEachItem for per-item transformations that use Python-native libraries:

{
  "type": "code",
  "parameters": {
    "language": "python",
    "mode": "runOnceForEachItem",
    "pythonCodeEachItem": "import json, re\nclean = re.sub(r'[^a-zA-Z0-9 ]', '', item['json']['text'])\nprint(json.dumps({'json': {'text': clean}}))",
    "maxConcurrency": 5,
    "timeout": 15000,
    "memoryLimit": 128
  }
}

Error Handling

ModeBehavior
stopHalts workflow on first error
continueSkips failed items, passes successful ones through
errorPortRoutes failed items to Error output port

Tips

Executes custom JavaScript or Python code in a secure sandbox to transform, filter, or generate workflow data. Use when you need programmatic logic, calculations, or complex transformations that can’t be achieved with other built-in tools. Produces one or more items as returned by the user code, depending on the execution mode.

Frequently asked questions

What's the difference between 'Run Once for All Items' and 'Run Once for Each Item'?

In 'Run Once for All Items' mode, your code is called once and receives every input item together — via `$input.all()` in JavaScript or a pre-loaded `items` list in Python — which is useful for aggregations or batch transforms. In 'Run Once for Each Item' mode, the code runs separately for each item, accessing it via `$input.item` (JavaScript) or `item` (Python). Choose per-item mode when your logic is stateless and item-independent; choose all-items mode when you need to compare or combine records.

How do I return data from my code so the next node can use it?

In JavaScript, you must explicitly return a value with the expected item structure — the node won't pick up data you write to a variable without returning it. In Python, you print JSON to stdout instead of using a return statement. In both cases the output must conform to BusyBot's item structure; returning plain strings or unstructured objects will cause downstream nodes to fail.

What happens if my script runs too long or uses too much memory?

The sandbox terminates your code when it exceeds the configured timeout or memory limit. Both limits are configurable in the node's parameters. If your code is killed this way, execution routes to the Error output rather than the normal Output, so you can wire up error-handling logic separately.

The node has two outputs — Output and Error. Do I have to handle the Error output?

You don't have to, but ignoring it means a script failure will silently stall that branch of your workflow. Connecting the Error output to a notification step or a fallback path is good practice, especially for scripts that call external logic or handle unpredictable input data.

Does the Code node need API keys or credentials to run?

No credentials are required. The node runs entirely within BusyBot's sandboxed environment, so there's nothing to configure in your credentials store. If your script itself needs to call an external API, you'd embed the key directly in the code or pass it in as a workflow variable — but that's your responsibility to manage, not the node's.

Build with the Code node

Drop it into a workflow, wire it to an agent, or call it on a schedule.

Open BusyBot

Last updated . Spotted something wrong? Tell us.