Loopfour
Blocks

Code block

Run JavaScript in a sandbox as a workflow step, read data from earlier steps and return a value that later steps can reference.

The Code block (type: "code") runs a short JavaScript function in a sandbox and stores what it returns, so later steps can use it. It has no plain-language guide; to map or filter records without writing code, see the Transform block.

When to use it

  • Calculate or reshape values that a template reference cannot express, such as summing invoice lines or grouping payments by customer.
  • Decode or re-encode base64 file content between steps.
  • Prepare a payload for the next step when an integration expects a specific structure.

The sandbox has no network or file access. To call an HTTP API, use the API Request block.

A Code step cannot use workflow secrets. A {{secrets.KEY}} reference anywhere in its config (including input) is refused when the workflow is saved, and a stored workflow that has one fails at run start. Call the API that needs the secret in an API Request step and pass its output to the code step through input.

Configuration

Field (config key)Editor labelTypeRequiredMeaning
codeCodestringYesThe body of an async function. Read input from input and return the result.
inputInput Data (JSON)objectNoThe value bound to input. Use template references here, such as {"invoices": "{{steps.list_invoices.data}}"}. When empty, input is the run input.
languageLanguagejavascript or typescriptNoDefault javascript. The sandbox runs the code as JavaScript; type annotations are not compiled away.
sandboxNot shownobjectNoLimits: timeoutMs (100 to 30000, default 5000; overrides timeout), maxOutputSize in bytes (1024 to 10485760, default 1048576), memoryLimitMb (16 to 512, default 128).
allowedLibrariesNot shownstring arrayNoHelper libraries exposed as globals. Default ["lodash", "dayjs", "validator"]. uuid and fflate can also be named.
codeReviewNot shownbooleanNoDefault true. Scans the code before it runs (see Errors and limits).
timeoutTimeout (ms)number or numeric textNoThe time limit in milliseconds, up to 30000 (30 s). The editor's default is 30000. Ignored when sandbox.timeoutMs is set. Without either, the limit is 5000.

What the code can use

  • input, plus standard JavaScript built-ins such as JSON, Math, Date, Array, Object, Map, Set, RegExp and Promise.
  • atob, btoa, TextEncoder, TextDecoder, typed arrays and a base64 helper for converting between base64 text and bytes.
  • The libraries in allowedLibraries. These are safe subsets of the named libraries, exposed as globals (lodash.map(...)), not full packages.

console output is not captured by default.

Output

The step stores this object. Reference it as {{steps.<step id>.<field>}}.

FieldTypeMeaning
resultanyThe value your code returned. Read it as {{steps.<step id>.result}} or a path inside it.
successbooleantrue when the step completed. A failed run of the code fails the step instead (see below).
metadataobjectExecution details, such as executionTimeMs and the sandbox limits used.
codeReviewobjectThe pre-run scan result, when codeReview is on.

The editor's output list also shows logs; the executor does not return that field.

Example

This workflow lists open Stripe invoices, then totals the amount due per customer.

{
  "name": "Open invoice totals by customer",
  "trigger": { "type": "api" },
  "steps": [
    {
      "id": "list_invoices",
      "type": "action",
      "name": "List open invoices",
      "action": "stripe.listInvoices",
      "config": { "status": "open" }
    },
    {
      "id": "total_by_customer",
      "type": "code",
      "name": "Total amount due by customer",
      "config": {
        "language": "javascript",
        "input": { "invoices": "{{steps.list_invoices.data}}" },
        "code": "const totals = {};\nfor (const inv of input.invoices || []) {\n  totals[inv.customer] = (totals[inv.customer] || 0) + inv.amount_due / 100;\n}\nreturn { totals, count: Object.keys(totals).length };",
        "sandbox": { "timeoutMs": 10000 }
      }
    }
  ]
}

A later step reads the totals as {{steps.total_by_customer.result.totals}}.

Errors and limits

  • Security scan. With codeReview on, the code text (comments excluded) is scanned before it runs, and code that matches a blocked pattern is rejected. Blocked patterns include eval(, Function, require(, import, process., globalThis, any constructor or __proto__ reference, built-in prototypes such as Object.prototype, Reflect.apply, file system calls and network calls such as fetch(. The scan matches text, so a property or string that contains one of these words is rejected too. Comments are ignored, and a method call such as /re/.exec(text) is allowed. The step fails with Code step failed [security] and the matched lines.
  • Runtime errors. A thrown error fails the step with Code step failed [runtime] and the error message.
  • Time limit. Code that runs longer than its limit (sandbox.timeoutMs, else timeout, else 5000 ms) fails the step. The ceiling is 30000 ms (30 s); a higher value is lowered to it, and 0 or a negative value is raised to 100 ms.
  • Output size. A returned value larger than sandbox.maxOutputSize as JSON fails the step with Code step failed [output_size]. Return only the fields later steps need, or raise the limit up to 10 MiB.
  • Use errorHandling on the step to continue or retry after a failure. See Errors, retries and timeouts.

On this page