Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Validate n8n expression syntax and fix common errors. Use when writing n8n expressions, using {{}} syntax, accessing $json/$node variables, troubleshooting expression errors, or working with webhook data in workflows.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-12 | ✗→✓ | ▲ Improved | 115% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 124% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 194% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 243% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 159% | 0% |
Expert guide for writing correct n8n expressions in workflows.
All dynamic content in n8n uses double curly braces:
{{expression}}Examples:
✅ {{$json.email}}
✅ {{$json.body.name}}
✅ {{$node["HTTP Request"].json.data}}
❌ $json.email (no braces - treated as literal text)
❌ {$json.email} (single braces - invalid)Access data from the current node:
javascript{{$json.fieldName}} {{$json['field with spaces']}} {{$json.nested.property}} {{$json.items[0].name}}
Access data from any previous node:
javascript{{$node["Node Name"].json.fieldName}} {{$node["HTTP Request"].json.data}} {{$node["Webhook"].json.body.email}}
Important:
Access current date/time:
javascript{{$now}} {{$now.toFormat('yyyy-MM-dd')}} {{$now.toFormat('HH:mm:ss')}} {{$now.plus({days: 7})}}
Access environment variables:
javascript{{$env.API_KEY}} {{$env.DATABASE_URL}}
Most Common Mistake: Webhook data is NOT at the root!
javascript{ "headers": {...}, "params": {...}, "query": {...}, "body": { // ⚠️ USER DATA IS HERE! "name": "John", "email": "john@example.com", "message": "Hello" } }
javascript❌ WRONG: {{$json.name}} ❌ WRONG: {{$json.email}} ✅ CORRECT: {{$json.body.name}} ✅ CORRECT: {{$json.body.email}} ✅ CORRECT: {{$json.body.message}}
Why: Webhook node wraps incoming data under .body property to preserve headers, params, and query parameters.
javascript// Simple nesting {{$json.user.email}} // Array access {{$json.data[0].name}} {{$json.items[0].id}} // Bracket notation for spaces {{$json['field name']}} {{$json['user data']['first name']}}
javascript// Node without spaces {{$node["Set"].json.value}} // Node with spaces (common!) {{$node["HTTP Request"].json.data}} {{$node["Respond to Webhook"].json.message}} // Webhook node {{$node["Webhook"].json.body.email}}
javascript// Concatenation (automatic) Hello {{$json.body.name}}! // In URLs https://api.example.com/users/{{$json.body.user_id}} // In object properties { "name": "={{$json.body.name}}", "email": "={{$json.body.email}}" }
Code nodes use direct JavaScript access, NOT expressions!
javascript// ❌ 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();
javascript// ❌ WRONG path: "{{$json.user_id}}/webhook" // ✅ CORRECT path: "user-webhook" // Static paths only
javascript// ❌ WRONG apiKey: "={{$env.API_KEY}}" // ✅ CORRECT Use n8n credential system, not expressions
Expressions must be wrapped in double curly braces.
javascript❌ $json.field ✅ {{$json.field}}
Field or node names with spaces require bracket notation:
javascript❌ {{$json.field name}} ✅ {{$json['field name']}} ❌ {{$node.HTTP Request.json}} ✅ {{$node["HTTP Request"].json}}
Node references are case-sensitive:
javascript❌ {{$node["http request"].json}} // lowercase ❌ {{$node["Http Request"].json}} // wrong case ✅ {{$node["HTTP Request"].json}} // exact match
Don't double-wrap expressions:
javascript❌ {{{$json.field}}} ✅ {{$json.field}}
For complete error catalog with fixes, see COMMON_MISTAKES.md
| Mistake | Fix | |---------|-----| | $json.field | {{$json.field}} | | {{$json.field name}} | {{$json['field name']}} | | {{$node.HTTP Request}} | {{$node["HTTP Request"]}} | | {{{$json.field}}} | {{$json.field}} | | {{$json.name}} (webhook) | {{$json.body.name}} | | '={{$json.email}}' (Code node) | $json.email |
For real workflow examples, see EXAMPLES.md
Webhook receives:
json{ "body": { "name": "John Doe", "email": "john@example.com", "message": "Hello!" } }
In Slack node text field:
New form submission!
Name: {{$json.body.name}}
Email: {{$json.body.email}}
Message: {{$json.body.message}}HTTP Request returns:
json{ "data": { "items": [ {"name": "Product 1", "price": 29.99} ] } }
In Email node (reference HTTP Request):
Product: {{$node["HTTP Request"].json.data.items[0].name}}
Price: ${{$node["HTTP Request"].json.data.items[0].price}}javascript// Current date {{$now.toFormat('yyyy-MM-dd')}} // Result: 2025-10-20 // Time {{$now.toFormat('HH:mm:ss')}} // Result: 14:30:45 // Full datetime {{$now.toFormat('yyyy-MM-dd HH:mm')}} // Result: 2025-10-20 14:30
javascript// First item {{$json.users[0].email}} // Array length {{$json.users.length}} // Last item {{$json.users[$json.users.length - 1].name}}
javascript// Dot notation (no spaces) {{$json.user.email}} // Bracket notation (with spaces or dynamic) {{$json['user data'].email}}
javascript// Concatenation (automatic) Hello {{$json.name}}! // String methods {{$json.email.toLowerCase()}} {{$json.name.toUpperCase()}}
javascript// Direct use {{$json.price}} // Math operations {{$json.price * 1.1}} // Add 10% {{$json.quantity + 5}}
javascript// Ternary operator {{$json.status === 'active' ? 'Active User' : 'Inactive User'}} // Default values {{$json.email || 'no-email@example.com'}}
javascript// Add days {{$now.plus({days: 7}).toFormat('yyyy-MM-dd')}} // Subtract hours {{$now.minus({hours: 24}).toISO()}} // Set specific date {{DateTime.fromISO('2025-12-25').toFormat('MMMM dd, yyyy')}}
javascript// Substring {{$json.email.substring(0, 5)}} // Replace {{$json.message.replace('old', 'new')}} // Split and join {{$json.tags.split(',').join(', ')}}
"Cannot read property 'X' of undefined" → Parent object doesn't exist → Check your data path
"X is not a function" → Trying to call method on non-function → Check variable type
Expression shows as literal text → Missing {{ }} → Add curly braces
String:
.toLowerCase(), .toUpperCase().trim(), .replace(), .substring().split(), .includes()Array:
.length, .map(), .filter().find(), .join(), .slice()DateTime (Luxon):
.toFormat(), .toISO(), .toLocal().plus(), .minus(), .set()Number:
.toFixed(), .toString()+, -, *, /, %.bodyEssential Rules:
.bodyMost Common Mistakes:
{{$json.name}} in webhooks → Use {{$json.body.name}}{{$json.email}} in Code → Use $json.email{{$node.HTTP Request}} → Use {{$node["HTTP Request"]}}For more details, see:
Need Help? Reference the n8n expression documentation or use n8n-mcp validation tools to check your expressions.
Other measured skills in the registry, with their headline benchmark lift.