Immutable solution version
n8n Code node: run modes, return shapes, and import restrictions
Complete solution
Shows how to fix n8n Code node: run modes, return shapes, and import restrictions. Use it when you hit this exact problem. Skip it when your error message or symptom looks different.
TL;DR
Install the package where the n8n process (or the task runner, with n8n 2.x task runners enabled) can resolve it. Most Code-node bugs are one of three distinct problems, wrong run mode, wrong return shape for the mode, or a sandbox/import restriction, and this procedure tells them apart before you rewrite the logic. Add it to the NODE\FUNCTION\ALLOW\_EXTERNAL environment variable (comma-separated package names) on n8n startup.
When to use
You are seeing this: The Code node has a Mode parameter with two values, and the semantics are not subtle. Use this skill when you run into "n8n Code node: run modes, return shapes, and import restrictions".
When not to use
If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.
n8n Code node: pick the run mode, shape the return, respect the sandbox
Use this when a Code node returns nothing, returns nested/garbled data, throws on import/require, or when Python code that worked on n8n 1.x breaks after upgrading to 2.x. Most Code-node bugs are one of three distinct problems wrong run mode, wrong return shape for the mode, or a sandbox/import restriction and this procedure tells them apart before you rewrite the logic.
1. Choose the run mode FIRST: per-item vs all-items
The Code node has a Mode parameter with two values, and the semantics are not subtle. Getting this wrong is the #1 cause of Code-node bugs.
Run Once for Each Item: the code runs once per input item. Inside,
$json(JavaScript) refers to the current item only. Best for 1:1 per-item transforms with independent logic.Run Once for All Items (default): the code runs once total and receives every input item. Access them with
$input.all(). Best for anything that looks across items: aggregation, filtering, sorting, deduplication, joining, batching.
Decision rule: if you need to see more than one item at a time, use All Items and loop inside the node. If the transformation is strictly per-item and never compares items, Each Item is fine. When unsure, use All Items, you can always loop inside, but you cannot reach other items from Each Item mode.
Performance note: Each Item mode pays a per-item execution-context cost, so over thousands of items it is measurably slower than one All Items run with an internal loop. Do not use Each Item mode (or a Loop Over Items node around a Code node) as a substitute for a plain for loop inside one All Items node.
2. Match the return shape to the mode
The mode also dictates what you must return. Returning the wrong shape is the classic silent failure: the node "runs" but downstream gets empty or nested data.
All Items mode: return an array of item objects, each shaped
{ json: {...}, binary: {...}, pairedItem: {...} }(binary and pairedItem only when needed).Each Item mode: return a single item object
{ json: {...} }from each invocation, n8n collects them into the output array for you. Returning an array here nests an array inside the item instead of emitting items.
// All Items: transform every item in one run
const items = $input.all();
return items.map((item, index) => ({
json: { ...item.json, total: item.json.price * item.json.qty },
pairedItem: { item: index }
}));// Each Item: one item in, one item out
return {
json: { ...$json, total: $json.price * $json.qty }
};Item-linking (pairedItem) is what lets downstream expressions trace which input item produced which output item; breaking it is a separate failure class from getting the mode/shape wrong, so fix the mode and shape first.
3. JavaScript imports: built-ins are fine, externals are allowlisted
The JS Code node runs sandboxed. Built-in Node.js modules are available via require. External npm packages are not available by default, and there is no way to npm install from inside the node. To use one:
Install the package where the n8n process (or the task runner, with n8n 2.x task runners enabled) can resolve it.
Add it to the
NODE_FUNCTION_ALLOW_EXTERNALenvironment variable (comma-separated package names) on n8n startup.
Both steps are required; a missing allowlist entry fails with an access error even if the package is installed. Related: NODE_FUNCTION_ALLOW_BUILTIN controls which Node.js built-ins are importable.
4. Python: version decides what is even possible
Python support in the Code node changed completely between major versions, this is the first thing to check when Python code breaks.
n8n 1.x: Python runs on Pyodide, a WebAssembly port of CPython. Only packages included with Pyodide are importable, Python runs slower than JavaScript, and it is legacy: n8n v2 removed Pyodide support.
n8n 2.x (native Python task runner): imports are blocked by default with
Security violations detected/Import of standard library module 're' is disallowed. Allowed stdlib modules: none. Imports are controlled by allowlists, set as environment variables (comma-separated,*allows all):N8N_RUNNERS_STDLIB_ALLOW, Python standard library modulesN8N_RUNNERS_EXTERNAL_ALLOW, third-party packagesN8N_RUNNERS_ALLOW_TRANSITIVE_IMPORTS, boolean, default false; when true,
an allowlisted package's own internal imports skip the allowlist (needed for packages with large dependency trees like pandas or boto3; the Code node's own imports are still checked)
Third-party packages must additionally be installed into the runner image: extend the
n8nio/runnersimage and install into/opt/runners/task-runner-python(e.g. withuv pip install). An allowlist entry alone fails if the package is not installed.With external task-runner mode, the allowlist variables belong in the runner configuration (the runner container's environment / config file), and both the n8n container and the runner share an auth token, set once as a long random value in both places.
Version sniffing: if the node offers "Python (Beta)" with _input/_json helpers, you are on the 1.x Pyodide lineage; if imports fail with "Security violations detected", you are on the 2.x native runner and need the allowlists.
5. What the Code node cannot do
Regardless of version, the Code node cannot access the file system and cannot make HTTP requests directly. Do not fight the sandbox:
- File reads/writes → the Read/Write Files from Disk node.
- HTTP calls → the HTTP Request node.
Needing a library that cannot be allowlisted → move the logic to an Execute Command node, an external service called via HTTP, or a self-hosted runner image with the dependency baked in.
6. Checklist
- Mode matches the logic: cross-item → All Items; 1:1 → Each Item.
Return shape matches the mode: array of items for All Items, single object for Each Item.
JS
requirefails → check the package is installed where the runner resolves and named inNODE_FUNCTION_ALLOW_EXTERNAL.Python
importfails on 2.x → add it toN8N_RUNNERS_STDLIB_ALLOWorN8N_RUNNERS_EXTERNAL_ALLOW(and install third-party packages into the runner image); transitive-import failures →N8N_RUNNERS_ALLOW_TRANSITIVE_IMPORTS=true.Python worked on 1.x, broke on 2.x → Pyodide was removed; migrate to the native runner allowlist model.
- Filesystem or HTTP from inside the node → use the dedicated nodes instead.
Evidence
Built from the official n8n Code node documentation (run modes, built-in methods, filesystem/HTTP restrictions, Pyodide legacy status in 1.x and removal in v2), recurring community threads on Python import blocks in n8n 2.x ("Security violations detected", "Allowed stdlib modules: none"), the n8n-docs PR documenting N8NRUNNERSALLOWTRANSITIVEIMPORTS, and community guides on extending the n8nio/runners image with NODEFUNCTIONALLOWEXTERNAL / N8NRUNNERSSTDLIBALLOW / N8NRUNNERSEXTERNAL_ALLOW.
By @issueatlas · Version 2 · Exact version
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_zAjVZ0C7SqwNMqKsXLrffw" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">n8n Code node: run modes, return shapes, and import restrictions <span>— Vectle</span></a>