How to Use Code Runner to Extend AI Workflows with Custom Logic
Write custom JavaScript or Python code to handle logic that's too specific for AI or built-in tools.
What This Integration Does
AI is great at fuzzy reasoning, and built-in connectors cover common integrations - but sometimes you need a specific calculation, a regex you trust, or a parser for a format nobody else uses. The Code Runner connector lets you drop a JavaScript or Python snippet directly into a workflow, with input from previous steps and output that downstream steps can consume like any other tool result.
The code runs in a sandbox: deterministic, isolated, no filesystem or arbitrary network access. That makes Code Runner the right tool for transformations and calculations - and a poor fit for "call an external API" (use the http connector for that instead).
Prerequisites
- The code connector enabled in your workspace.
- A clear idea of the input shape your code expects and the output shape downstream steps need.
Step 1: Identify Where AI Stops and Deterministic Code Starts
Use Code Runner when the answer is one right answer (a calculation, a regex match, a checksum) and the AI Agent for anything ambiguous (categorization, summarization, copy). A common pattern: AI extracts fields, Code Runner validates and computes derived values, then downstream connectors act on the result.
Step 2: Stage the Input
Add a Transform node before the code step to assemble exactly the input the snippet needs - one object with named fields. This keeps your code from depending on the shape of upstream tools and makes it portable across workflows.
Step 3: Add a Code Runner Step
Drop a Connector node pointing at the code connector. Pick execute-javascript or execute-python. Your input is available as data. The last expression evaluated is the step's return value.
JavaScript example - order analytics:
const orders = data.orders;
const total = orders.reduce((s, o) => s + o.total, 0);
const aov = total / orders.length;
const top = orders.flatMap(o => o.items)
.reduce((map, i) => ({ ...map, [i.name]: (map[i.name] || 0) + i.qty }), {});
const topProduct = Object.entries(top).sort((a, b) => b[1] - a[1])[0]?.[0];
({ totalRevenue: total, averageOrderValue: aov, topProduct });
Python example - hash and HMAC for a webhook signature:
import hmac, hashlib, json
payload = json.dumps(data['body'], separators=(',', ':')).encode()
signature = hmac.new(data['secret'].encode(), payload, hashlib.sha256).hexdigest()
{'signature': signature}
Step 4: Use a Built-in Utility When You Can
Before reaching for code, check whether a built-in connector already does it: json (get, set, merge, pick, omit), math (sum, average, round, currency), text (case, slugify, truncate), regex (extract, replace), encoding (hash-sha256, hmac). These run faster than user code and don't need maintenance.
Step 5: Hand the Result to the Next Step
The object you return is now available as the step's result. Use it in any downstream connector. Example - feed computed analytics straight into slack send-message or into mongodb insert-documents.
Step 6: Guard Against Failures
Always wrap risky logic in try/catch (JS) or try/except (Python) and return a structured result with an ok flag. Then add a Condition node downstream that branches on ok - successful results flow normally, failures route to a slack alert or a Human review node.
Tips
- Keep snippets short - if you're writing more than ~50 lines, split the logic into smaller code steps so each one is independently testable.
- Return objects, not strings. Downstream variable picking is far easier with structured output.
- Use Python for anything number-heavy (statistics, dates) and JS for anything string- or JSON-heavy. Both work, but you'll write less code with the right one.
Common Pitfalls
- Reaching for the network - the sandbox blocks outbound calls. If you need to hit an API, use the http connector, not Code Runner.
- Unhandled exceptions - an uncaught error fails the step. Wrap with try/catch and return a structured failure rather than crashing the whole workflow.
- Returning
undefined(JS) - if the last expression doesn't evaluate, the step returnsnull. Always wrap the return in parentheses or use an explicit object literal at the end.
Testing
Add a Manual trigger and feed a representative input through just the code step. Inspect the result. Then build the rest of the workflow around it. Code Runner steps are the easiest part of a workflow to unit-test in isolation - take advantage of that before wiring up dependencies.