When to Use
- Complex business logic that can't be expressed in UI nodes: A customer tier calculation depends on spend, recency, and product category in a multi-step if/else tree. DataMapping and CollectionOperation can't express this — CodeExecute can.
- String manipulation and parsing: Extract an order number from a free-text email subject using a regular expression. Parse a custom pipe-delimited data format. Build a formatted reference string combining multiple fields with business-specific padding rules.
- Date arithmetic: Calculate the number of business days between two dates. Determine whether a given date falls in Q1 or Q2. Add 30 calendar days to a start date and return the result as ISO format.
- Custom validation algorithm: Validate a complex password policy, an ISBN-13 checksum, or a LUHN credit card number — all require programmatic logic that is impossible to express declaratively in UI nodes.
- Data transformation combining multiple fields: Construct a composite index key by hashing multiple fields. Build a slug from a product title. Normalize an irregular address format by combining and reformatting multiple address fields into a single canonical string.
Configuration
| Setting | Required | Description |
Script |
Required |
The JavaScript code to execute. All workflow variables are injected as JavaScript globals before the script runs. The script must assign a value to the result variable — this value becomes the node's output data. Scripts that do not assign result produce a null output (not an error). |
JavaScript Runtime
| Property | Value |
| Engine | Jint v4.1.0 — embedded ECMAScript engine (no Node.js, no browser APIs) |
| Language version | ECMAScript 5.1 fully supported; partial ES6 support: let, const, arrow functions, template literals, destructuring |
| Execution timeout | 5 seconds (hard limit in high-isolation mode). Scripts exceeding 5 seconds are terminated and route to the error port. |
| Available globals | Math, Date, JSON, Array, String, Number, RegExp, Object, parseInt, parseFloat, isNaN, isFinite |
| Workflow variable access | All workflow variables (set by VariableAssignment nodes) are injected as JavaScript globals. Access them by name directly: var tier = customerTier; |
Sandbox restrictions — strictly enforced: The following are blocked in high-isolation mode: eval, Function constructor, require, fetch, XMLHttpRequest, setTimeout, setInterval, clearTimeout, clearInterval, process, file system APIs. Scripts attempting to use these receive a SecurityException that routes to the error port. Network access, file system access, and process spawning are not possible from CodeExecute.
Output Ports
| Port | When It Fires |
success | The script completes within the 5-second timeout without throwing an unhandled exception. The value of the result variable (which may be null if never assigned) is available as the node output. |
error | The script throws an unhandled exception, exceeds the 5-second timeout, contains a syntax error detected at parse time, or attempts to use a sandboxed/blocked API. Error output includes error_message, error_type ("Timeout", "RuntimeError", "SyntaxError", "SecurityException"), and the script line number where the error occurred. |
Output Fields
| Field | Type | Description |
result | any | The value assigned to the JavaScript result variable by the script. Can be a string, number, boolean, object, or array. If the script never assigns result, this field is null. Access downstream as {{ $output.codeExecuteNode.result }}. |
Sample Script — Order Filtering and ID Extraction
// Workflow variable 'orders' is an array of order objects
// Select orders over $100 and return their IDs
var allOrders = orders; // injected from VariableAssignment
result = allOrders
.filter(function(o) { return o.total > 100; })
.map(function(o) { return o.id; });
Sample Script — Business Day Calculation
// Calculate business days between startDate and endDate
// Both injected as ISO date strings from workflow variables
function isWeekend(d) {
var day = d.getDay();
return day === 0 || day === 6;
}
var start = new Date(startDate);
var end = new Date(endDate);
var count = 0;
var current = new Date(start);
while (current <= end) {
if (!isWeekend(current)) { count++; }
current.setDate(current.getDate() + 1);
}
result = { businessDays: count, startDate: startDate, endDate: endDate };
Sample Script — Custom Tier Calculation
// customerAnnualSpend and customerRecencyDays injected from workflow variables
var spend = customerAnnualSpend;
var recency = customerRecencyDays;
var tier = "bronze";
if (spend > 50000 && recency < 30) {
tier = "platinum";
} else if (spend > 20000 && recency < 60) {
tier = "gold";
} else if (spend > 5000 && recency < 90) {
tier = "silver";
}
result = { tier: tier, annualSpend: spend, recencyDays: recency };
Sample Configuration
{
"language": "javascript",
"code": "const items = $input.all();\nconst total = items.reduce((sum, item) => sum + item.json.amount, 0);\nreturn [{ json: { total, count: items.length, average: total / items.length } }];",
"timeout": 30000
}
Sample Output
Success Port
{
"total": 15750.00,
"count": 12,
"average": 1312.50,
"_executionTime": 42,
"_language": "javascript"
}
Expression Reference
| Expression | Value |
{{ $output.codeExecuteNode.result }} | The value assigned to result in the script. If result is an object, further dot navigation works: {{ $output.codeExecuteNode.result.tier }}. |
{{ $output.codeExecuteNode.result.businessDays }} | Access a property of an object result. |
Node Policies & GuardRails
| Policy | Rationale |
| NEVER attempt file system or HTTP calls from CodeExecute | The sandbox blocks these APIs. Attempting them wastes execution time before the SecurityException fires. Use the HttpRequest node for HTTP calls and dedicated storage nodes for file access. |
| No async/await or Promises | Jint executes synchronously. async functions and await keywords are not supported and will cause a SyntaxError. All script logic must be synchronous and complete within 5 seconds. |
Always assign to result at the end of the script | Forgetting to assign result produces a null output without an error. The success port fires, but downstream nodes receive null. Make the last line of every script an explicit result = ... assignment. |
| Keep scripts under 50 lines — use Function for longer logic | CodeExecute is designed for compact, focused transformations. Scripts longer than ~50 lines are harder to maintain and test. For complex multi-step logic, use the Function node which supports configurable timeouts and cleaner organization. |
| Handle the error port — timeout errors are real | A script processing a large array may hit the 5-second limit under load. Connect the error port to a notification node and log the error payload (which includes error_type: "Timeout") for monitoring. |
Use var declarations for all variables | Although Jint supports let and const as ES6 extensions, using var throughout ensures compatibility with all Jint v4.1 edge cases and makes scripts easier to debug in isolation. |
Pattern Examples
Pattern 1 — Regex Extraction from Free-Text
Extract an order number from an email subject line using a regular expression.
// emailSubject injected from workflow variable
var subject = emailSubject;
var match = subject.match(/ORD-\d{4,10}/);
if (match) {
result = { found: true, orderId: match[0] };
} else {
result = { found: false, orderId: null };
}
Pattern 2 — LUHN Checksum Validation
// cardNumber injected from workflow variable (string of digits)
var digits = cardNumber.replace(/\D/g, "").split("").map(Number);
var sum = 0;
var isOdd = true;
for (var i = digits.length - 1; i >= 0; i--) {
var d = digits[i];
if (!isOdd) {
d *= 2;
if (d > 9) d -= 9;
}
sum += d;
isOdd = !isOdd;
}
result = { valid: sum % 10 === 0, cardNumber: cardNumber };
Pattern 3 — Construct Composite Index Key
// tenantId, entityType, entityId injected from workflow variables
var key = [tenantId, entityType, entityId]
.map(function(s) { return String(s).toLowerCase().replace(/[^a-z0-9]/g, "_"); })
.join(":");
result = { indexKey: key };