Node: Script
The Script node runs code that you write to calculate values from the data of previous nodes — form responses, approval results, outputs of other scripts. The results (text, number, list of emails or list of objects) can be used in the following nodes: in the text of emails, in conditions, in recipients and in other text fields.
The node runs on its own, without waiting for any external action, and moves on as soon as the code finishes.
When to use
Use the Script node when a value that the process needs does not exist ready-made in any form. Common examples:
- Calculations — sum items, apply a discount, calculate a deadline or total amount from several responses.
- Building texts — compose a message or an email subject with parts of different responses.
- Choosing recipients — return a list of emails that depends on the responses (for example, the manager of each branch).
- Tables in emails — return a list of rows (item, quantity, value) to appear as a table in the body of the email.
- Deciding the path — calculate a number or a text to use as a condition in an If/Else node.
The code is written in TypeScript in an editor with autocomplete. For simple rules, such as showing the answer to a field, prefer the regular workflow variables: the Script node is for when you need to calculate.
Configuration
Click the node on the workflow editor canvas. The side panel has three tabs, Inputs, Outputs and Test, and the Code area right below them. The shortcuts Alt+I, Alt+O and Alt+T switch tabs; they do not work while you are typing in a field or in the code editor.
Inputs — what the script reads
Each input gives the script the data of one previous node of the workflow. Click Add input and fill in:
| Field | Description |
|---|---|
| Previous node | The node the data comes from ("Select a previous node"). Only nodes that come before the Script in the flow appear. |
| Variable name | The name the code uses to access this data. See the naming rules. |
What the script receives depends on the type of the selected node:
| Previous node | What the script receives |
|---|---|
| Form Response trigger, Request Form Response and Request Follow-Up | The form response, with one item per question (number, text, date, chosen options, etc.) and information about the response. The editor's autocomplete shows the real fields of the form. |
| Approval | The node name, the approval result and the comment of whoever responded. Before the response, only the name. |
| Scheduled trigger | The node name and the scheduled time. |
| Trigger: Action Plan and Request Action Plan | The action plan data of that node. |
| Another Script node | The outputs that the other script returned. This is how a script uses the result of another, including lists of objects. |
| Other nodes (Wait, Send Email, Create PDF, etc.) | The node name and the time the flow reached it. |
Webhook, Slack, Teams, Google Sheets, Excel, Google Drive and OneDrive cannot be inputs, because they do not produce data for the script to read.
The format of the data reflects what the previous node has at the moment the script runs. If the form or the action plan changes later, the data received changes along with it.
Outputs — what the script returns
Each output is a value that the script delivers to the following nodes. Click Add output, choose the Type and give it a name. There are four types:
| Type | What it is | Where it can be used |
|---|---|---|
| Text | A sentence or a word. A date returned as text arrives at the destination as text in ISO format (for example, 2026-03-01T10:00:00.000Z). | Texts in general (emails, status, file name) and conditions. |
| Number | A valid number. NaN and infinity are rejected. | Texts in general and conditions. |
| Email list | A list of email addresses. | Recipients of the email nodes ("Add from a Script node"). |
| Object list | A table: each item of the list is a row, and you declare the attributes (columns), each of type Text or Number. | Only in the body of an email, as a table, or as an input of another Script node. |
Every declared output must come back in the script's result, with the declared type. If one is missing, comes with a different type, or if a row of a list lacks an attribute, the node fails and the message says which output or row caused the problem. Anything the script returns beyond the declared outputs is discarded.
The object list appears as a table in the body of the five email nodes: Approval, Send Email, Request Form Response, Request Follow-Up and Request Action Plan. It does not work in the subject, the status, nor in Slack, Teams, webhook, spreadsheet or Drive.
Code
The code has a fixed structure rule: the calculateValue function must be the first thing in the code, with the signature below. Helper functions and constants go after it, never before.
function calculateValue({ order, approval }: Context): Result {
const total = calculateTotal(order);
return { total, summary: `Total: ${total}` };
}
function calculateTotal(order: Context['order']): number {
// helper functions go after calculateValue
return 0;
}
- Between the braces of the signature, list the names of the inputs that the script uses (
order,approval). - The function returns an object, with one key for each declared output.
try/catch,throwandErrorare allowed: use them to handle expected situations and return a default value.- Blocked words, which prevent the code from being saved:
async,await,import,importScripts,eval,then,prototype,__proto__,setTimeout,setInterval,constructor,fetchandXMLHttpRequest. The script has no access to the internet, files or timers. - The code can have up to 100,000 characters.
- A syntax error is reported with the line of the problem, and the workflow cannot be published until the code compiles.
The code is compiled when the draft is saved, which happens on its own every 30 seconds or when you close the node panel. If the warning "Code not compiled yet" appears, wait for the automatic save; if the warning persists, fix the syntax errors.
Naming rules
| Name | Rule | Why |
|---|---|---|
| Input (variable name) and Output | Only letters without accents, numbers and _; starts with a letter; up to 60 characters; cannot be a reserved JavaScript word (such as class or return) nor one of the blocked words of the code (such as then). | The name becomes a variable in the code and a key used in the texts ({{script...}}). An accent, hyphen or space would break both. |
| Attribute of an object list | Free (it can have spaces in the middle and accents), except the characters , " & < > }, and with no space at the start or the end. | These characters interfere with the column list of the email table (,), the HTML text (& < > ") and the closing of the variable (}). Identical names in the same list are not accepted either. |
Two inputs, or two outputs, cannot have the same name.
Using the results in the following nodes
The outputs appear in the Script group of the variable picker of the text fields, and in two other places:
- Texts — in the subject and body of the email nodes, in the status of the Set Status node, and in the file name and content of Create PDF. The value goes into the text in place of the variable.
- Conditions — in a rule of type Script (node, output, operator and value). Outputs of type Text or Number work. On the arrow that leaves the Script itself, the rule can also use the outputs of that same Script. If the output changes type or is removed later, the rule shows "The output changed type or was removed. Review the output, the operator and the value of this rule."
- Recipients — in the email nodes, Add from a Script node uses an output of type Emails. Repeated or invalid addresses are ignored, and what was discarded is recorded in the history.
Link and table in the email body
- A text in the format
[label](url), in an output of type Text, becomes a clickable link in the email body (onlyhttpandhttpsaddresses). In the subject and the other fields, the text appears as it was written. - An object list becomes a table in the email body, with one column per attribute. The variable picker always includes the column list, in the order you select them. An empty list shows only the header.
Texts coming from form responses, when they enter the email through a script, do not run code or improper formatting: the content is shown as text.
Testing the script
The Test tab, next to Inputs and Outputs, runs the script without triggering the workflow. It only appears for those who can edit the workflow:
- Click Load sample context. The Context field is filled with an example for each input, in the real format of the chosen node, using the forms that are on the screen.
- Adjust the values of the example for the case you want to simulate. If you add or rename an input later, the missing keys are added to the context when you run, without losing what you already edited.
- Click Run. The Result appears beside it, or the error message, if any.
Points of attention:
- The test uses the code that is on the screen, without needing to save the draft first. Syntax errors, signature errors or blocked words appear in the Result.
- The test and the real execution have the same limit of 10 seconds per execution, and 64 MB of memory. Exceeding the time shows "The script exceeded the 10-second limit".
- The server accepts 2 tests at the same time. If there are more, "Too many tests are running. Wait a few seconds and try again" appears: just try again. The tests never delay the scripts of running workflows, which have their own slots.
- If the Context is not valid JSON, "The provided context is not valid JSON." appears.
- The Context can be up to 256 KB. Above that, "The test context exceeds the 256 KB limit" appears, and the test does not even start.
When the script fails
If the script exceeds 10 seconds or 64 MB, throws an unhandled error, returns an output with the wrong type, or returns a result larger than 256 KB, the node fails. As a result:
- The instance gets the status Failed, and the workflow owner receives an email about it, with the link to see the events.
- The error appears in the instance history, with the cause (for example, which output or row was wrong).
- The script's input data is not sent to error monitoring tools nor recorded in the server log, because it may contain form responses.
Use try/catch for predictable cases (empty field, division by zero) and return a default value. This way the instance moves on instead of failing.
When the previous node did not run
The workflow only guarantees that there is a path from the previous node to the Script, not that the node has already run. This happens, for example, when the Script reads a node from the other side of an If/Else, or when an approval has not been answered yet.
In these cases the data arrives empty (the input arrives as an object with no data, the text appears blank), and the node that read the data shows in the instance history the warning "Empty data from nodes that had not run yet", with the name of each node. The workflow does not fail because of this: handle the empty case in the code.
This is different from a failure to read the form or the response (for example, a momentary database outage): in that case the script does not run with empty data. The instance gets the Failed status, the workflow owner receives the warning email, and the error appears in the history as a script failure.
Best Practices
- Use names that explain the value:
order_totalandmanager_emailshelp more thanxandlist. - Declare only the inputs you use: the script receives only what you configured, and this keeps the autocomplete cleaner.
- Test before publishing: use Load sample context, adjust the values with extreme cases (empty field, empty list) and run.
- Keep the script short: each script should calculate a set of values. For different steps, chain two Script nodes.
- Combine with the Set Status node: a status before the Script helps you know, in the instances panel, which step the instance is in.