---
title: Advanced Transformations
slug: advanced-transformations
docTags: 
createdAt: 2025-08-11T11:13:45.000Z
---

Need something more complex than basic transformations? Want to write the code yourself?

You can use advanced transformations to write complex JSONata expressions, which gives you significant flexibility to transform data according to your needs. See [JSONata Docs](https://docs.jsonata.org/overview.html) to assist you in writing expressions.

:::hint{type="info"}
JSONata requires **double quotes** (`"`) for all string values. Single quotes (`'`) are not valid string delimiters and will cause expressions to fail. To include a literal double quote inside a string, escape it with a backslash (`\"`). For example: `$stringCapitalize("This is a \"test\"")`. See [Using the Transform Data Native Action](docId\:tAIY8leYf1ZvgMhHDYBCf) in the main Transform Data guide for details.
:::

:::hint{type="warning"}
Once you click **Switch to advanced** in the block header, you cannot revert the block to a basic (no-code) chain for that block.
:::

:::hint{type="warning"}
A confirmation dialog asks **Are you sure you want to switch to advanced mode?** and explains that switching is **irreversible** and that existing transformations for the block will be converted. Click **Confirm** to continue or **Cancel** to stay in basic mode.
:::

## Advanced Mode Layout

In **advanced** mode, each block uses the same three areas described in [Using the Transform Data Native Action](docId\:tAIY8leYf1ZvgMhHDYBCf):

| Area               | Advanced mode behavior                                                                                                                                                                                                                                                           |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Inputs**         | Declare the data the block can use (**+ Add property**), or let **Add Playbook Property** / **Add Expression** add rows for you. Mark inputs as **sensitive** with the lock icon.                                                                                                |
| **Transformation** | A **code editor** for the JSONata expression. Under the editor, use **Add Playbook Property** and **Add Expression** to map playbook data in one step. Use **Code Editor Configuration** to set line numbers, folding, and **Theme** (for example Dracula, Monokai, or Eclipse). |
| **Test**           | Hidden until you click **Test** in the block header. Then provide test data, run **Test**, review **Result** or **Discovered Outputs**, and use **Copy inputs to editor** when needed.                                                                                           |

In the **code editor**, you can **paste** JSONata from elsewhere. Every playbook-backed value you use must have a row in the **Inputs** list. The editor offers **autocomplete** or **IntelliSense**-style help for declared inputs and updates as you add or change inputs.

### Add Playbook Property and Add Expression

In **advanced** mode, the footer under the code editor includes:

| Control                   | What it does                                                                                                                                                             |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Add Playbook Property** | Opens the playbook property drawer. When you select a property, Turbine **adds** the mapping to **Inputs** and **inserts** the JSONata path at the cursor in the editor. |
| **Add Expression**        | Opens the expression dialog. When you enter an expression, Turbine **adds** the mapping to **Inputs** and **inserts** the path at the cursor.                            |

Input names follow the same nested naming as in earlier Transform Data versions (for example `actions.http1.result.body` or `event.data.href`). You can still review and edit every input in the **Inputs** area. Use **+ Add property** when you prefer to declare inputs manually before writing JSONata.

**Sensitive data** is set **per input** in the **Inputs** list.

When might you want to use advanced transformations? The most common need is transforming one object structure into a different structure for use within the playbook.

## Transforming One Object Structure to a Different Structure Use Case

Avery takes data from a Slack event and restructures it to Swimlane’s common data model. Avery uses an advanced transformation **block** and:

1. Clicks **Add Playbook Property** under the code editor and selects fields from the Slack trigger (Turbine adds them to **Inputs** and inserts paths in the editor), or defines **inputs** manually with **+ Add property**.
2. Writes or refines JSONata in the **code editor**, using **dot** or **bracket** paths for objects and arrays as required.
3. Clicks **Test** in the block header to open the test panel, runs **Test**, and reviews **Discovered Outputs** when needed.

Avery sets up a webhook trigger for Slack events, adds a **Transform Data** action, switches a block to **advanced**, and builds an object (for example id, type, timestamp) from those inputs.

Visit the [JSONata Exerciser](https://try.jsonata.org/) to verify and/or practice writing JSONata expressions.

:::hint{type="info"}
**Add Playbook Property** and **Add Expression** update **Inputs** and the expression together. If you **delete** or **rename** an input in the **Inputs** panel, Turbine rewrites matching references in the expression (deleted inputs become `$DELETED` in the code). If you remove a reference only by editing the expression, **remove** the unused **input** yourself in **Inputs**. Keep the **Inputs** list aligned with what the expression uses.
:::

## Handle Errors With `$error` and `$assert`

In **advanced** mode, you can use Swimlane JSONata extensions to fail a block with a clear, custom message:

| Function                      | Purpose                                                                      |
| ----------------------------- | ---------------------------------------------------------------------------- |
| `$error(message)`             | Stop evaluation and fail the block with the message you provide.             |
| `$assert(condition, message)` | Fail the block when `condition` is false, using `message` as the error text. |

When the block fails, Turbine records the message on the playbook run. Starting in Turbine **26.2.0**, that error is also exposed as a **playbook property** so downstream actions can map `$actions.<transformationActionName>.error.<blockKey>.message` (and related fields) without parsing the run log manually.

**Example — validate before transform:**

```jsonata
$assert($exists(email) and $string(email) != "", "Missing required field: email")
{
  "email": email,
  "domain": $split(email, "@")[1]
}
```

If `email` is missing, the block fails with **Missing required field: email**. A later action can reference `$actions.myTransform.error.block_1.message` to log the failure, update a record, or branch in a condition.

For property paths and downstream mapping, see [Using the Transform Data Native Action](docId\:tAIY8leYf1ZvgMhHDYBCf) in the main Transform Data guide.

## See Also

- [Using the Transform Data Native Action](docId\:tAIY8leYf1ZvgMhHDYBCf) — block setup, testing, outputs, and quoting rules
