Agent Skill
2/7/2026

n8n-workflows

Build n8n workflow automations - nodes, expressions, JavaScript code, and integration patterns. Use when creating or debugging n8n workflows.

A
allanninal
0GitHub Stars
1Views
npx skills add allanninal/claude-code-skills

SKILL.md

Namen8n-workflows
DescriptionBuild n8n workflow automations - nodes, expressions, JavaScript code, and integration patterns. Use when creating or debugging n8n workflows.

name: n8n-workflows description: Build n8n workflow automations - nodes, expressions, JavaScript code, and integration patterns. Use when creating or debugging n8n workflows.

n8n Workflow Automation

When to Use This Skill

  • Building n8n workflows
  • Writing n8n expressions
  • Creating Code nodes (JavaScript/Python)
  • Debugging workflow errors
  • Integrating n8n with external services

n8n Basics

Workflow Structure

Trigger Node → Processing Nodes → Output Nodes
     ↓              ↓                  ↓
  Webhook      Transform Data     Send Email
  Schedule     HTTP Request       Slack Message
  Manual       Code Node          Database Write

Node Types

TypeExamplesPurpose
TriggerWebhook, Schedule, ManualStart workflow
ActionHTTP Request, Email, SlackDo something
TransformSet, Function, SplitModify data
FlowIf, Switch, MergeControl logic
DataPostgres, MongoDB, RedisData operations

Expressions

Basic Syntax

// Access input data
{{ $json.fieldName }}

// Access specific item
{{ $('Node Name').item.json.field }}

// Access all items from a node
{{ $('Node Name').all() }}

// First/last item
{{ $('Node Name').first().json.field }}
{{ $('Node Name').last().json.field }}

// Current item index
{{ $itemIndex }}

// Workflow variables
{{ $vars.myVariable }}

Common Patterns

// Conditional value
{{ $json.status === 'active' ? 'Yes' : 'No' }}

// Default value
{{ $json.name ?? 'Unknown' }}
{{ $json.name || 'Unknown' }}

// String manipulation
{{ $json.email.toLowerCase() }}
{{ $json.name.split(' ')[0] }}

// Date formatting
{{ $now.format('YYYY-MM-DD') }}
{{ $json.date.toFormat('dd/MM/yyyy') }}

// Array operations
{{ $json.items.length }}
{{ $json.items.map(i => i.name).join(', ') }}
{{ $json.items.filter(i => i.active) }}

Built-in Variables

// Current timestamp
{{ $now }}
{{ $today }}

// Workflow info
{{ $workflow.id }}
{{ $workflow.name }}

// Execution info
{{ $execution.id }}
{{ $execution.mode }}

// Environment
{{ $env.API_KEY }}

Code Node (JavaScript)

Basic Structure

// Process each item
for (const item of $input.all()) {
  // Access data
  const name = item.json.name;
  const email = item.json.email;

  // Modify data
  item.json.processed = true;
  item.json.fullName = `${item.json.firstName} ${item.json.lastName}`;
}

return $input.all();

Return New Items

const newItems = [];

for (const item of $input.all()) {
  // Create new item structure
  newItems.push({
    json: {
      id: item.json.id,
      name: item.json.name.toUpperCase(),
      timestamp: new Date().toISOString(),
    },
  });
}

return newItems;

HTTP Requests in Code

const response = await fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${$env.API_KEY}`,
  },
  body: JSON.stringify({
    query: $json.query,
  }),
});

const data = await response.json();

return [{ json: data }];

Error Handling

try {
  const result = await riskyOperation();
  return [{ json: { success: true, data: result } }];
} catch (error) {
  // Option 1: Return error as data
  return [{ json: { success: false, error: error.message } }];

  // Option 2: Throw to stop workflow
  throw new Error(`Operation failed: ${error.message}`);
}

Async Operations

// Multiple parallel requests
const promises = $input.all().map(async (item) => {
  const response = await fetch(`https://api.example.com/users/${item.json.id}`);
  const user = await response.json();
  return { json: { ...item.json, user } };
});

return await Promise.all(promises);

Code Node (Python)

Basic Structure

# Access input items
items = _input.all()
new_items = []

for item in items:
    data = item.json

    # Process data
    result = {
        "name": data.get("name", "").upper(),
        "processed_at": datetime.now().isoformat(),
    }

    new_items.append({"json": result})

return new_items

Limitations

# Available modules:
# - datetime, json, math, os (limited)
# - No external package imports
# - No file system access
# - No subprocess

# For HTTP requests, use HTTP Request node instead

Common Workflow Patterns

Webhook → Process → Response

Webhook Trigger
     ↓
  Set Node (transform data)
     ↓
  HTTP Request (call API)
     ↓
  Respond to Webhook

Scheduled Data Sync

Schedule Trigger (every hour)
     ↓
  HTTP Request (fetch source data)
     ↓
  Split In Batches
     ↓
  Postgres (upsert records)
     ↓
  Slack (notify completion)

Error Handling Pattern

Main Flow
     ↓
  Try/Catch
     ├─ Success → Continue
     └─ Error → Error Handler
                    ↓
                Slack Alert
                    ↓
                Log to Database

Conditional Processing

HTTP Request
     ↓
  IF (status check)
     ├─ True → Process A
     │            ↓
     │         Send Email
     └─ False → Process B
                   ↓
               Log Warning

Debugging

View Execution Data

// Log to execution output
console.log('Debug:', JSON.stringify($json, null, 2));

// In expressions, check intermediate values
{{ JSON.stringify($json) }}

Common Errors

## "Cannot read property 'X' of undefined"
- Check if previous node output exists
- Use optional chaining: $json.data?.items

## "Items do not match"
- Ensure consistent item count between branches
- Use Merge node to combine items

## Expression evaluation failed
- Check syntax (missing braces, quotes)
- Verify node names match exactly
- Use $('Node Name') not $('node name')

Test Workflow

# Pin data for testing
# 1. Execute workflow once
# 2. Click "Pin Data" on node output
# 3. Modify and test without re-triggering

Best Practices

Naming Conventions

- Descriptive node names: "Fetch User Data" not "HTTP Request"
- Use prefixes for flow: "IF: Check Status", "Merge: Combine Results"
- Version your workflows: "Email Processor v2"

Error Handling

- Always add error handling for external requests
- Use "On Error" settings on critical nodes
- Set up alerting for workflow failures
- Log errors to persistent storage

Performance

- Use "Split In Batches" for large datasets
- Avoid nested loops in Code nodes
- Cache external data when possible
- Use pagination for API requests

Security

- Store secrets in credentials, not expressions
- Use environment variables for config
- Validate webhook payloads
- Limit webhook exposure (authentication)

Credentials

// Access credentials in Code node
const apiKey = $credentials.myApi.apiKey;

// In expressions
{{ $credentials.myApi.apiKey }}

// Best practice: Use HTTP Request node
// with built-in credential support

Checklist

  • Use descriptive node names
  • Add error handling for external calls
  • Test with edge cases (empty data, errors)
  • Use Split In Batches for large datasets
  • Store secrets in credentials
  • Add notes explaining complex logic
  • Set up failure notifications
  • Version control workflow exports
Skills Info
Original Name:n8n-workflowsAuthor:allanninal