Claude Agent Skill · by Czlonkowski

N8n Expression Syntax

Install N8n Expression Syntax skill for Claude Code from czlonkowski/n8n-skills.

Install
Terminal · npx
$npx skills add https://github.com/czlonkowski/n8n-skills --skill n8n-expression-syntax
Works with Paperclip

How N8n Expression Syntax fits into a Paperclip company.

N8n Expression Syntax drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.

S
SaaS FactoryPaired

Pre-configured AI company — 18 agents, 18 skills, one-time purchase.

$27$59
Explore pack
Source file
SKILL.md525 lines
Expand
---name: n8n-expression-syntaxdescription: 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.--- # n8n Expression Syntax Expert guide for writing correct n8n expressions in workflows. --- ## Expression Format 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)``` --- ## Core Variables ### $json - Current Node Output Access data from the current node: ```javascript{{$json.fieldName}}{{$json['field with spaces']}}{{$json.nested.property}}{{$json.items[0].name}}``` ### $node - Reference Other Nodes Access data from any previous node: ```javascript{{$node["Node Name"].json.fieldName}}{{$node["HTTP Request"].json.data}}{{$node["Webhook"].json.body.email}}``` **Important**:- Node names **must** be in quotes- Node names are **case-sensitive**- Must match exact node name from workflow ### $now - Current Timestamp Access current date/time: ```javascript{{$now}}{{$now.toFormat('yyyy-MM-dd')}}{{$now.toFormat('HH:mm:ss')}}{{$now.plus({days: 7})}}``` ### $env - Environment Variables Access environment variables: ```javascript{{$env.API_KEY}}{{$env.DATABASE_URL}}``` **Warning**: Some n8n instances have `N8N_BLOCK_ENV_ACCESS_IN_NODE` enabled, which blocks `$env` access entirely. If `$env` returns errors, use alternative approaches:- Store values in credentials instead- Use a Set node with manually entered values- Pass values through webhook query parameters --- ## 🚨 CRITICAL: Webhook Data Structure **Most Common Mistake**: Webhook data is **NOT** at the root! ### Webhook Node Output Structure ```javascript{  "headers": {...},  "params": {...},  "query": {...},  "body": {           // ⚠️ USER DATA IS HERE!    "name": "John",    "email": "john@example.com",    "message": "Hello"  }}``` ### Correct Webhook Data Access ```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. --- ## Common Patterns ### Access Nested Fields ```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']}}``` ### Reference Other Nodes ```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}}``` ### Combine Variables ```javascript// Concatenation (automatic)Hello {{$json.body.name}}! // In URLshttps://api.example.com/users/{{$json.body.user_id}} // In object properties{  "name": "={{$json.body.name}}",  "email": "={{$json.body.email}}"}``` --- ## When NOT to Use Expressions ### ❌ Code Nodes Code nodes use **direct JavaScript access**, NOT expressions! ```javascript// ❌ WRONG in Code nodeconst email = '={{$json.email}}';const name = '{{$json.body.name}}'; // ✅ CORRECT in Code nodeconst email = $json.email;const name = $json.body.name; // Or using Code node APIconst email = $input.item.json.email;const allItems = $input.all();``` ### ❌ Webhook Paths ```javascript// ❌ WRONGpath: "{{$json.user_id}}/webhook" // ✅ CORRECTpath: "user-webhook"  // Static paths only``` ### ❌ Credential Fields ```javascript// ❌ WRONGapiKey: "={{$env.API_KEY}}" // ✅ CORRECTUse n8n credential system, not expressions``` --- ## Validation Rules ### 1. Always Use {{}} Expressions **must** be wrapped in double curly braces. ```javascript❌ $json.field✅ {{$json.field}}``` ### 2. Use Quotes for Spaces and Special Characters Field or node names with spaces, diacritics, or special characters require **bracket notation**: ```javascript❌ {{$json.field name}}✅ {{$json['field name']}} ❌ {{$node.HTTP Request.json}}✅ {{$node["HTTP Request"].json}} // Bracket notation is mandatory for keys with special characters✅ {{$json['Gross Price w/o shipment']}}✅ {{$json['Cena brutto zł']}}``` ### 3. Match Exact Node Names Node references are **case-sensitive**: ```javascript❌ {{$node["http request"].json}}  // lowercase❌ {{$node["Http Request"].json}}  // wrong case✅ {{$node["HTTP Request"].json}}  // exact match``` ### 4. No Nested {{}} Don't double-wrap expressions: ```javascript❌ {{{$json.field}}}✅ {{$json.field}}``` --- ## Common Mistakes For complete error catalog with fixes, see [COMMON_MISTAKES.md](COMMON_MISTAKES.md) ### Quick Fixes | 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` | --- ## Working Examples For real workflow examples, see [EXAMPLES.md](EXAMPLES.md) ### Example 1: Webhook to Slack **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}}``` ### Example 2: HTTP Request to Email **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}}``` ### Example 3: Format Timestamp ```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``` --- ## Data Type Handling ### Arrays ```javascript// First item{{$json.users[0].email}} // Array length{{$json.users.length}} // Last item{{$json.users[$json.users.length - 1].name}}``` ### Objects ```javascript// Dot notation (no spaces){{$json.user.email}} // Bracket notation (with spaces or dynamic){{$json['user data'].email}}``` ### Strings ```javascript// Concatenation (automatic)Hello {{$json.name}}! // String methods{{$json.email.toLowerCase()}}{{$json.name.toUpperCase()}}``` ### Numbers ```javascript// Direct use{{$json.price}} // Math operations{{$json.price * 1.1}}  // Add 10%{{$json.quantity + 5}}``` --- ## Advanced Patterns ### Conditional Content ```javascript// Ternary operator{{$json.status === 'active' ? 'Active User' : 'Inactive User'}} // Default values{{$json.email || 'no-email@example.com'}}``` ### Date Manipulation ```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')}}``` ### String Manipulation ```javascript// Substring{{$json.email.substring(0, 5)}} // Replace{{$json.message.replace('old', 'new')}} // Split and join{{$json.tags.split(',').join(', ')}}``` --- ## Debugging Expressions ### Test in Expression Editor 1. Click field with expression2. Open expression editor (click "fx" icon)3. See live preview of result4. Check for errors highlighted in red ### Common Error Messages **"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 --- ## Expression Helpers ### Available Methods **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()`- Math operations: `+`, `-`, `*`, `/`, `%` --- ## Best Practices ### ✅ Do - Always use {{ }} for dynamic content- Use bracket notation for field names with spaces- Reference webhook data from `.body`- Use $node for data from other nodes- Test expressions in expression editor ### ❌ Don't - Don't use expressions in Code nodes- Don't forget quotes around node names with spaces- Don't double-wrap with extra {{ }}- Don't assume webhook data is at root (it's under .body!)- Don't use expressions in webhook paths or credentials --- ## Related Skills - **n8n MCP Tools Expert**: Learn how to validate expressions using MCP tools- **n8n Workflow Patterns**: See expressions in real workflow examples- **n8n Node Configuration**: Understand when expressions are needed --- ## Summary **Essential Rules**:1. Wrap expressions in {{ }}2. Webhook data is under `.body`3. No {{ }} in Code nodes4. Quote node names with spaces5. Node names are case-sensitive **Most Common Mistakes**:- Missing {{ }} → Add braces- `{{$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:- [COMMON_MISTAKES.md](COMMON_MISTAKES.md) - Complete error catalog- [EXAMPLES.md](EXAMPLES.md) - Real workflow examples --- **Need Help?** Reference the n8n expression documentation or use n8n-mcp validation tools to check your expressions.