All skills
wilkomarketing avatar

/n8n-expression-syntax

@0d187d8

Validate n8n expression syntax and fix common errors. Use when writing n8n expressions, using {{}} syntax, accessing $json/$node variables, troubleshooting expression errors, mapping data between nodes, or referencing webhook data in workflows. Use this skill whenever configuring node fields that reference data from previous nodes — expressions are how n8n passes data between nodes, and getting the syntax wrong is the most common source of workflow errors. Also use when asked whether a complex expression hurts performance.

Use this Skill: https://skilld.dev/gh/wilkomarketing/antigravity-n8n-skills/n8n-expression-syntax

This session only. Nothing lands on disk.

COMMON_MISTAKES.md

≈2.4k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Common n8n Expression Mistakes

Complete catalog of expression errors with explanations and fixes.


1. Missing Curly Braces

Problem: Expression not recognized, shows as literal text

❌ Wrong:

$json.email

✅ Correct:

{{$json.email}}

Why it fails: n8n treats text without {{ }} as a literal string. Expressions must be wrapped to be evaluated.

How to identify: Field shows exact text like "$json.email" instead of actual value.


2. Webhook Body Access

Problem: Undefined values when accessing webhook data

❌ Wrong:

{{$json.name}}
{{$json.email}}
{{$json.message}}

✅ Correct:

{{$json.body.name}}
{{$json.body.email}}
{{$json.body.message}}

Why it fails: Webhook node wraps incoming data under .body property. The root $json contains headers, params, query, and body.

Webhook structure:

{
  "headers": {...},
  "params": {...},
  "query": {...},
  "body": {         // User data is HERE!
    "name": "John",
    "email": "john@example.com"
  }
}

How to identify: Webhook workflow shows "undefined" for fields that are definitely being sent.


3. Spaces in Field Names

Problem: Syntax error or undefined value

❌ Wrong:

{{$json.first name}}
{{$json.user data.email}}

✅ Correct:

{{$json['first name']}}
{{$json['user data'].email}}

Why it fails: Spaces break dot notation. JavaScript interprets space as end of property name.

How to identify: Error message about unexpected token, or undefined when field exists.


4. Spaces in Node Names

Problem: Cannot access other node's data

❌ Wrong:

{{$node.HTTP Request.json.data}}
{{$node.Respond to Webhook.json}}

✅ Correct:

{{$node["HTTP Request"].json.data}}
{{$node["Respond to Webhook"].json}}

Why it fails: Node names are treated as object property names and need quotes when they contain spaces.

How to identify: Error like "Cannot read property 'Request' of undefined"


5. Incorrect Node Reference Case

Problem: Undefined or wrong data returned

❌ Wrong:

{{$node["http request"].json.data}}  // lowercase
{{$node["Http Request"].json.data}}  // wrong capitalization

✅ Correct:

{{$node["HTTP Request"].json.data}}  // exact match

Why it fails: Node names are case-sensitive. Must match exactly as shown in workflow.

How to identify: Undefined value even though node exists and has data.


6. Double Wrapping

Problem: Literal {{ }} appears in output

❌ Wrong:

{{{$json.field}}}

✅ Correct:

{{$json.field}}

Why it fails: Only one set of {{ }} is needed. Extra braces are treated as literal characters.

How to identify: Output shows "{{value}}" instead of just "value".


7. Array Access with Dots

Problem: Syntax error or undefined

❌ Wrong:

{{$json.items.0.name}}
{{$json.users.1.email}}

✅ Correct:

{{$json.items[0].name}}
{{$json.users[1].email}}

Why it fails: Array indices require brackets, not dots. Number after dot is invalid JavaScript.

How to identify: Syntax error or "Cannot read property '0' of undefined"


8. Using Expressions in Code Nodes

Problem: Literal string instead of value, or errors

❌ Wrong (in Code node):

const email = '{{$json.email}}';
const name = '={{$json.body.name}}';

✅ Correct (in Code node):

const email = $json.email;
const name = $json.body.name;

// Or using Code node API
const email = $input.item.json.email;
const allItems = $input.all();

Why it fails: Code nodes have direct access to data. The {{ }} syntax is for expression fields in other nodes, not for JavaScript code.

How to identify: Literal string "{{$json.email}}" appears in Code node output instead of actual value.


9. Missing Quotes in $node Reference

Problem: Syntax error

❌ Wrong:

{{$node[HTTP Request].json.data}}

✅ Correct:

{{$node["HTTP Request"].json.data}}

Why it fails: Node names must be quoted strings inside brackets.

How to identify: Syntax error "Unexpected identifier"


10. Incorrect Property Path

Problem: Undefined value

❌ Wrong:

{{$json.data.items.name}}       // items is an array
{{$json.user.email}}            // user doesn't exist, it's userData

✅ Correct:

{{$json.data.items[0].name}}    // access array element
{{$json.userData.email}}        // correct property name

Why it fails: Wrong path to data. Arrays need index, property names must be exact.

How to identify: Check actual data structure using expression editor preview.


11. Using = Prefix Outside JSON

Problem: Literal "=" appears in output

❌ Wrong (in text field):

Email: ={{$json.email}}

✅ Correct (in text field):

Email: {{$json.email}}

Note: The = prefix is only needed in JSON mode or when you want to set entire field value to expression result:

// JSON mode (set property to expression)
{
  "email": "={{$json.body.email}}"
}

// Text mode (no = needed)
Hello {{$json.body.name}}!

Why it fails: The = is parsed as literal text in non-JSON contexts.

How to identify: Output shows "=john@example.com" instead of "john@example.com"


12. Expressions in Webhook Path

Problem: Path doesn't update, validation error

❌ Wrong:

path: "{{$json.user_id}}/webhook"
path: "users/={{$env.TENANT_ID}}"

✅ Correct:

path: "my-webhook"              // Static paths only
path: "user-webhook/:userId"    // Use dynamic URL parameters instead

Why it fails: Webhook paths must be static. Use dynamic URL parameters (:paramName) instead of expressions.

How to identify: Webhook path doesn't change or validation warns about invalid path.


13. Forgetting .json in $node Reference

Problem: Undefined or wrong data

❌ Wrong:

{{$node["HTTP Request"].data}}          // Missing .json
{{$node["Webhook"].body.email}}         // Missing .json

✅ Correct:

{{$node["HTTP Request"].json.data}}
{{$node["Webhook"].json.body.email}}

Why it fails: Node data is always under .json property (or .binary for binary data).

How to identify: Undefined value when you know the node has data.


14. Template Literals & Concatenation Outside {{ }}

Problem: A backtick template literal or + concatenation shows up as literal text

❌ Wrong (written as the whole field value, with no {{ }}):

`Hello ${$json.name}!`          // bare backticks — printed verbatim
"Hello " + $json.name + "!"     // bare concatenation — printed verbatim

✅ Correct (any of these):

Hello {{$json.name}}!                   // adjacent text + {{ }} auto-concatenate
{{ `Hello ${$json.name}!` }}            // a template literal INSIDE {{ }}
{{ "Hello " + $json.name + "!" }}       // + concatenation INSIDE {{ }}

Why it fails: n8n only evaluates what's inside {{ }}; everything else is literal text. The backticks and + aren't the problem — the missing {{ }} is. Inside an expression, backtick template literals with ${...} interpolation are fully supported modern JavaScript, so this is valid and evaluates:

={{ $json.items.map(i => `${i.name} — ${i.qty}`).join(', ') }}

The same holds for optional chaining ({{ $json.user?.email }}) and string-keyed bracket access ({{ $json['some-prop'] }}) — both are valid n8n expressions. As of n8n-mcp ≥ 2.63.0 the validator no longer flags template literals, optional chaining, or bracket access inside expressions (earlier versions raised false-positive errors on them).

How to identify: Literal backticks or + symbols appear in output → the code wasn't wrapped in {{ }}.


15. Empty Expression Brackets

Problem: Literal {{}} in output

❌ Wrong:

{{}}
{{ }}

✅ Correct:

{{$json.field}}                 // Include expression content

Why it fails: Empty expression brackets have nothing to evaluate.

How to identify: Literal "{{ }}" text appears in output.


Quick Reference Table

Error Symptom Fix
No {{ }} Literal text Add {{ }}
Webhook data Undefined Add .body
Space in field Syntax error Use ['field name']
Space in node Undefined Use ["Node Name"]
Wrong case Undefined Match exact case
Double {{ }} Literal braces Remove extra {{ }}
.0 array Syntax error Use [0]
{{ }} in Code Literal string Remove {{ }}
No quotes in $node Syntax error Add quotes
Wrong path Undefined Check data structure
= in text Literal = Remove = prefix
Dynamic path Doesn't work Use static path
Missing .json Undefined Add .json
Template literal / + outside {{ }} Literal text Wrap in {{ }} (both work inside)
Empty {{ }} Literal braces Add expression

Debugging Process

When expression doesn't work:

  1. Check braces: Is it wrapped in {{ }}?
  2. Check data source: Is it webhook data? Add .body
  3. Check spaces: Field or node name has spaces? Use brackets
  4. Check case: Does node name match exactly?
  5. Check path: Is the property path correct?
  6. Use expression editor: Preview shows actual result
  7. Check context: Is it a Code node? Remove {{ }}

Related: See EXAMPLES.md for working examples of correct syntax.

Source: SKILL.md on GitHub

1 alert6mo4 checks · Risk HIGH
  • Gen Agent Trust Hub7mo

    The skill instructs the AI on n8n syntax but promotes insecure programming patterns, specifically raw interpolation of untrusted data into SQL queries and exposing API keys in URLs, which creates significant injection and data exposure risks.

  • Socket6mo

    No alerts

  • Snyk7mo

    Risk: MEDIUM · No issues

  • Runlayer6mo

    4 files scanned · No issues

Signed by skilld at 0d187d8. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated 3 months ago

README badge

README badge for wilkomarketing/antigravity-n8n-skills/n8n-expression-syntax