Expressions
Relevant source files
The following files were used as context for generating this wiki page:
- packages/frontend/editor-ui/src/utils/templates/samples/tutorial/expressions_tutorial.json
- packages/@n8n/ai-workflow-builder.ee/evaluations/chains/evaluators/expressions-evaluator.ts
- packages/frontend/editor-ui/src/utils/expressions.ts
- packages/frontend/editor-ui/src/utils/expressions.test.ts
- packages/testing/playwright/tests/ui/9-expression-editor-modal.spec.ts
- packages/testing/playwright/tests/ui/11-inline-expression-editor.spec.ts
- packages/@n8n/ai-workflow-builder.ee/src/chains/prompts/base/expression-rules.ts
- packages/@n8n/task-runner/src/js-task-runner/built-ins-parser/tests/built-ins-parser.test.ts
- packages/@n8n/ai-workflow-builder.ee/src/tools/prompts/main-agent.prompt.ts
Expressions are the "glue" that connects nodes in an n8n workflow, allowing for dynamic data referencing and manipulation. They are small pieces of JavaScript code, enclosed in double curly braces {{ }}, that get replaced with a value when the workflow runs. This enables passing data from one node to another, performing calculations, transforming data, and implementing conditional logic.
The expression system is a cornerstone of n8n's flexibility, providing access to a wide range of built-in variables and helpers for interacting with node data, execution context, and environment variables. From simple data lookups to complex data transformations using JavaScript, expressions empower users to build powerful and dynamic automation workflows.
Sources: packages/frontend/editor-ui/src/utils/templates/samples/tutorial/expressions_tutorial.json:18-21, packages/@n8n/ai-workflow-builder.ee/evaluations/chains/evaluators/expressions-evaluator.ts:10-11
Core Concepts
Syntax
Expressions are identified by double curly braces. For a field to be treated as an expression, it must be prefixed with an equals sign (=).
- Pure Expression:
={{ $('Node Name').item.json.field }} - Mixed String and Expression:
="Text prefix {{ expression }} text suffix"
The = prefix is required to tell n8n to evaluate the content. Without it, a string containing {{ }} will be treated as a literal string.
Sources: packages/@n8n/ai-workflow-builder.ee/evaluations/chains/evaluators/expressions-evaluator.ts:40-42, packages/@n8n/ai-workflow-builder.ee/src/chains/prompts/base/expression-rules.ts:3-7
Frontend Handling
The frontend provides several utilities and components to work with expressions, including an inline editor and a full-screen modal.
shouldConvertToExpression: A utility that checks if a string contains{{and}}and doesn't start with=, suggesting it should be converted to an expression.completeExpressionSyntax: Automatically adds the=prefix and closing braces if a user types{{.unwrapExpression: A utility to remove the{{and}}from an expression string.
Sources: packages/frontend/editor-ui/src/utils/expressions.ts:13-15, 114-129, packages/frontend/editor-ui/src/utils/expressions.test.ts:59-88
The following diagram illustrates the user interaction flow for entering an expression in the UI.
Data Access
Expressions provide powerful ways to access data from the current node, previous nodes, or any node in the workflow.
Data Access Flow
This diagram shows the typical chain of properties used to access data from another node.
Node & Item Selectors
You can select which node's data to access and which item(s) from that node's output.
| Selector | Description | Example |
|---|---|---|
$('Node Name') | Selects a node by its name. | {{ $('Source Data').item.json.name }} |
$json | A shorthand to access the JSON data from the single previous node's output. Equivalent to $input.item.json. | {{ $json.name }} |
$input | References the input data for the current node. | {{ $input.item.json.myStr }} |
.item | Selects the data of the current item in a loop or paired execution. Often equivalent to .last() if a node only has one output item. | {{ $('Source Data').item.json.name }} |
.first() | Gets the data from the first item of a node's output. | {{ $('Node Name').first().json.field }} |
.last() | Gets the data from the last item of a node's output. | {{ $('Node Name').last().json.field }} |
.all() | Gets data from ALL items, returning it as an array of objects. | {{ $('Node Name').all() }} |
Sources: packages/frontend/editor-ui/src/utils/templates/samples/tutorial/expressions_tutorial.json:83-93, 235-250, packages/@n8n/ai-workflow-builder.ee/evaluations/chains/evaluators/expressions-evaluator.ts:15-19, packages/testing/playwright/tests/ui/9-expression-editor-modal.spec.ts:88-111
Data Structure Navigation
Once you have selected an item, you can navigate its data structure.
- Dot Notation for Objects: Access object properties using a dot (
.).- Example:
{{ $('Source Data').last().json.contact.email }}
- Example:
- Bracket Notation for Arrays: Access array elements by their zero-based index using brackets
[].- Example:
{{ $('Source Data').last().json.skills[1] }}(accesses the second skill)
- Example:
- Combining Both: Access properties of objects inside an array.
- Example:
{{ $('Source Data').last().json.projects[0].status }}(gets the status of the first project)
- Example:
JavaScript in Expressions
Since expressions are executed as JavaScript, you can use standard JavaScript functions and objects.
- String Manipulation:
{{ $json.name.toUpperCase() }} - Math Operations:
{{ Math.round($json.age / 7) }} - Type Checking:
{{ typeof $json.age }} - Object Inspection:
{{ Object.keys($json.contact) }} - JSON Utilities:
{{ JSON.stringify($json.contact, null, 2) }} - Array Methods:
{{ $('Split Out Skills').all().map(item => item.json.skills).join(', ') }}
Sources: packages/frontend/editor-ui/src/utils/templates/samples/tutorial/expressions_tutorial.json:201-213, 271-274, 300-302, 330-332, packages/testing/playwright/tests/ui/14-data-transformation-expressions.spec.ts
Built-in Variables & Helpers
n8n provides a rich set of built-in variables for accessing workflow metadata, environment variables, and other contextual information.
| Variable/Helper | Description |
|---|---|
$env | Access environment variables. |
$vars | Access workflow static variables. |
$secrets | Access credentials secrets. |
$execution | Access metadata about the current execution (e.g., id, mode). |
$workflow | Access metadata about the workflow (e.g., id, name). |
$now | A Luxon DateTime object for the current date and time. |
$today | A Luxon DateTime object for the start of the current day. |
$itemIndex | The index of the current item being processed. |
$runIndex | The index of the current run in a loop. |
$prevNode | Information about the node that executed just before the current one. |
$parameter | Accesses other parameters within the same node. |
$fromAI(...) | A special helper for AI Tool nodes to dynamically populate parameters. |
Sources: packages/@n8n/ai-workflow-builder.ee/evaluations/chains/evaluators/expressions-evaluator.ts:24-32, packages/@n8n/task-runner/src/js-task-runner/built-ins-parser/tests/built-ins-parser.test.ts:200-241, packages/frontend/editor-ui/src/constants.ts:468-490
Special $fromAI Expression
Tool nodes (those with types ending in "Tool") support a special $fromAI expression. This allows an AI Agent to dynamically populate parameters at runtime based on the conversation context.
Syntax: ={{ $fromAI('key', 'description', 'type', defaultValue) }}
Example: In a Gmail Tool node, the "To" field can be set to ={{ $fromAI('to') }}. The AI agent will then fill in the recipient's email address during execution.
{
"sendTo": "={{ $fromAI('to') }}",
"subject": "={{ $fromAI('subject') }}",
"message": "={{ $fromAI('message_html') }}"
}
This expression is only supported in tool nodes and is crucial for creating dynamic, AI-driven workflows.
Sources: packages/@n8n/ai-workflow-builder.ee/src/tools/prompts/main-agent.prompt.ts:220-250, packages/@n8n/ai-workflow-builder.ee/evaluations/chains/evaluators/expressions-evaluator.ts:20-22
Error Handling and Display
The UI provides feedback on the validity of an expression.
Expression States
An expression can be in one of three states:
| State | Description | UI Display Example |
|---|---|---|
valid | The expression is syntactically correct and resolves to a value. | hello |
pending | The expression is valid, but its value cannot be determined yet (e.g., depends on a node that hasn't been executed). | [Execute previous nodes for preview] |
invalid | The expression contains a syntax error or references non-existent data. | [ERROR: No input connected] |
Sources: packages/frontend/editor-ui/src/utils/expressions.ts:63-75, packages/testing/playwright/tests/ui/9-expression-editor-modal.spec.ts:92-94
Common Error Messages
The getExpressionErrorMessage function formats errors for the UI.
| Error Type | Message |
|---|---|
no_execution_data | [Execute previous nodes for preview] |
no_input_connection | [ERROR: No input connected] |
paired_item_no_info | Error related to missing paired item data, often when a node hasn't run. |
Sources: packages/frontend/editor-ui/src/utils/expressions.ts:77-107, packages/frontend/editor-ui/src/utils/expressions.test.ts:11-20
Result Stringification
The stringifyExpressionResult function controls how the resolved value of an expression is displayed in the UI.
nullresults in an empty string.- An empty string
''results in the text[empty]. NaNis displayed as"NaN".- Errors are formatted with an
[ERROR: ...]prefix.
Sources: packages/frontend/editor-ui/src/utils/expressions.ts:109-129, packages/frontend/editor-ui/src/utils/expressions.test.ts:22-38
Summary
Expressions are a fundamental and powerful feature in n8n. They provide the necessary mechanism for creating dynamic and data-driven workflows by allowing nodes to communicate and share data. Mastering expressions, from basic data access to leveraging the full power of JavaScript and n8n's built-in helpers, is key to unlocking the full potential of the platform.