Files
claude-skills/skills/n8n-workflow-specialist/TROUBLESHOOTING.md
felix.zoesch c3f0fc2c12 Add n8n workflow specialist skill
Comprehensive skill for n8n workflow automation including:
- Workflow design and node configuration
- Expression writing reference (14 KB)
- Comprehensive troubleshooting guide (15 KB)
- Examples for common use cases
- Performance optimization tips

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 12:54:23 +01:00

15 KiB

n8n Troubleshooting Guide

Common issues and solutions for n8n workflow debugging.

Table of Contents

Authentication Errors

401 Unauthorized

Symptoms:

  • HTTP Request node returns 401 status code
  • Error message: "Unauthorized" or "Invalid credentials"

Common Causes & Solutions:

  1. Incorrect Credentials

    • Check that the correct credential is selected in the node
    • Verify the credential contains the right API key/token
    • Re-create the credential if suspicious
  2. Expired Token

    • OAuth2 tokens expire - reconnect the credential
    • API keys may have expiration dates - check provider dashboard
    • Refresh tokens if using OAuth2
  3. Wrong Authentication Method

    • Verify API requires Bearer token, Basic Auth, or API Key
    • Check API documentation for correct header format
    • Common headers:
      • Authorization: Bearer TOKEN
      • Authorization: Basic BASE64_CREDENTIALS
      • X-API-Key: YOUR_KEY
  4. Missing Headers

    // Common required headers
    {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json",
      "User-Agent": "n8n-workflow"
    }
    
  5. Incorrect Scope/Permissions

    • OAuth2 credential may lack required scopes
    • API key may not have permission for the endpoint
    • Check provider's permission settings

Debugging Steps:

# Test authentication manually with curl
curl -H "Authorization: Bearer YOUR_TOKEN" \
     -H "Content-Type: application/json" \
     https://api.example.com/endpoint

# Check if token is valid
curl -H "Authorization: Bearer YOUR_TOKEN" \
     https://api.example.com/me

403 Forbidden

Symptoms:

  • HTTP Request returns 403 status code
  • "Access Denied" or "Forbidden" error

Solutions:

  1. Insufficient Permissions

    • API key/token lacks permission for the resource
    • Check if account has access to the endpoint
    • Verify subscription/plan level
  2. IP Whitelist

    • Some APIs require IP whitelisting
    • Add n8n server IP to allowed list
    • Check firewall rules
  3. Rate Limiting

    • Too many requests in short time
    • Implement delays between requests
    • Use Split In Batches node with batch size limit

Expression Errors

"Cannot read property 'X' of undefined"

Cause: Trying to access a property that doesn't exist

Solutions:

// Bad: Will fail if user is undefined
{{ $json.user.email }}

// Good: Use optional chaining
{{ $json.user?.email }}

// Good: Provide default value
{{ $json.user?.email ?? 'no-email@example.com' }}

// Good: Check existence first
{{ $json.user && $json.user.email ? $json.user.email : 'N/A' }}

"Node not found"

Cause: Referenced node name doesn't match exactly

Solutions:

// Bad: Wrong node name
{{ $node["Http Request"].json }}

// Good: Exact match (case-sensitive)
{{ $node["HTTP Request"].json }}

// Best: Use debug panel to verify exact node name

Debugging:

  1. Check node name exactly as it appears in workflow
  2. Node names are case-sensitive
  3. Spaces and special characters must match exactly
  4. Renamed nodes? Update all expressions

Expression Syntax Errors

Common Mistakes:

// Bad: Missing quotes around property names with dashes
{{ $json.user-name }}

// Good: Use bracket notation
{{ $json["user-name"] }}

// Bad: Trying to use expressions in Code node
const value = {{ $json.value }}; // Won't work!

// Good: In Code node, access directly
const value = items[0].json.value;

// Bad: Wrong quotation marks in expression
{{ $json.text === "value" }}

// Good: Use single quotes in expressions
{{ $json.text === 'value' }}

DateTime Errors

"Invalid DateTime"

// Bad: Invalid date format
{{ DateTime.fromISO($json.badDate) }}

// Good: Validate before parsing
{{ $json.date ? DateTime.fromISO($json.date).toISO() : '' }}

// Good: Handle invalid dates
{{ DateTime.fromISO($json.date).isValid ?
   DateTime.fromISO($json.date).toFormat('yyyy-MM-dd') :
   'Invalid Date' }}

HTTP Request Errors

404 Not Found

Solutions:

  1. Verify URL

    // Check dynamic URLs evaluate correctly
    {{ `https://api.example.com/users/${$json.userId}` }}
    
    // Debug: Use Set node to see final URL
    // Set field "debug_url" to your URL expression
    
  2. Check API Endpoint

    • Endpoint may have changed (check API docs)
    • Verify API version in URL
    • Check for typos in path
  3. Resource Doesn't Exist

    • ID might be invalid
    • Resource might have been deleted
    • Test with known valid ID

Timeout Errors

"Request timed out"

Solutions:

  1. Increase Timeout

    • Go to node settings
    • Increase "Timeout" value (default: 300000ms = 5 minutes)
    • For slow APIs, increase to 600000ms (10 minutes)
  2. Optimize Request

    • Add pagination for large datasets
    • Request only needed fields
    • Use filtering on API side
    • Consider caching responses
  3. Check API Health

    • API might be down or slow
    • Test endpoint in browser/Postman
    • Check API status page

SSL/TLS Errors

"unable to verify the first certificate"

Solutions:

  1. Ignore SSL Issues (development only!)

    • In HTTP Request node settings
    • Enable "Ignore SSL Issues"
    • ⚠️ Not recommended for production
  2. Update Certificates

    • Update system certificates
    • Contact API provider about SSL issues

CORS Errors

Note: n8n workflows run server-side, so CORS shouldn't be an issue. If you see CORS errors:

  • You might be testing in browser (test in n8n instead)
  • The error might be from a different issue
  • Check actual error message in execution logs

Webhook Issues

"Webhook waiting for response"

Cause: Webhook is in "Respond to Webhook" mode but no response sent

Solution:

Webhook Node (Wait for Webhook Call)
  → Process Data
  → Respond to Webhook Node (REQUIRED)

Always add "Respond to Webhook" node when using "Wait for Webhook Call"

Webhook Not Triggering

Debugging Steps:

  1. Verify Workflow is Active

    • Workflow must be activated (not just saved)
    • Check toggle switch in top-right is ON
  2. Check Webhook URL

    • Copy exact URL from Webhook node
    • Verify no typos when configuring external service
    • Test with curl:
    curl -X POST https://your-n8n.com/webhook/your-path \
         -H "Content-Type: application/json" \
         -d '{"test": "data"}'
    
  3. Verify HTTP Method

    • Webhook expects POST but receiving GET (or vice versa)
    • Match method in Webhook node config
  4. Check Authentication

    • If "Webhook Authentication" is set, include credentials
    • Verify Header Auth name and value match
  5. Firewall/Network Issues

    • n8n instance must be accessible from internet
    • Check firewall rules
    • Verify DNS is resolving correctly

Webhook Returns Error to Caller

Customize response:

Webhook → IF Node
  → Success Path → Respond (200 OK)
  → Error Path → Respond to Webhook (400/500 with error message)

Use "Respond to Webhook" node to control:

  • Status code
  • Headers
  • Response body
  • Response format (JSON, text, etc.)

Data Transformation Problems

Empty Results After Transformation

Cause: Filter or map returns empty array

Debugging:

// Check what data looks like before transformation
// Add a Set node to inspect: {{ $json }}

// Ensure filter condition is correct
{{ $json.items.filter(item => item.status === 'active') }}

// Check if property exists
{{ $json.items.filter(item => item.status && item.status === 'active') }}

// Verify array is actually an array
{{ Array.isArray($json.items) ? $json.items.length : 0 }}

Data Type Mismatches

String vs Number Issues:

// Problem: Comparing string with number
{{ $json.age > 18 }} // Fails if age is "25" (string)

// Solution: Parse to number
{{ parseInt($json.age) > 18 }}
{{ parseFloat($json.price) > 99.99 }}

// Problem: Math on strings
{{ $json.price * 1.2 }} // Fails if price is "$99.99"

// Solution: Clean and parse
{{ parseFloat($json.price.replace('$', '')) * 1.2 }}

JSON Parse Errors

"Unexpected token in JSON"

Solutions:

// Problem: Invalid JSON string
JSON.parse($json.data)

// Solution: Validate first (in Code node)
try {
  const data = JSON.parse(items[0].json.rawData);
  return [{ json: data }];
} catch (error) {
  return [{ json: {
    error: 'Invalid JSON',
    raw: items[0].json.rawData
  }}];
}

// Solution: Check if already an object
if (typeof $json.data === 'string') {
  JSON.parse($json.data)
} else {
  $json.data
}

Performance Issues

Workflow Execution Too Slow

Solutions:

  1. Reduce HTTP Requests

    // Bad: Loop making individual requests
    Loop → HTTP Request (100x)
    
    // Good: Batch request
    Batch Items → HTTP Request with array
    
  2. Use Split In Batches

    Split In Batches (batch size: 10)
      → Process Batch
      → Loop Back
    
  3. Optimize Expressions

    // Bad: Complex expression repeated
    {{ $json.items.filter(...).map(...).reduce(...) }}
    
    // Good: Use Code node for complex logic
    const result = items[0].json.items
      .filter(item => item.active)
      .map(item => item.value)
      .reduce((sum, val) => sum + val, 0);
    return [{ json: { total: result } }];
    
  4. Cache Frequently Accessed Data

    • Store results in Set node
    • Reuse instead of re-fetching
    • Consider using database for persistent cache

Memory Errors

"JavaScript heap out of memory"

Solutions:

  1. Process in Batches

    • Don't load all data at once
    • Use Split In Batches node
    • Process incrementally
  2. Reduce Item Count

    • Add Limit node after triggers
    • Use pagination in API requests
    • Filter data at source
  3. Optimize Data Size

    • Remove unnecessary fields with Set node
    • Don't store large binary data in JSON
    • Use binary data type for files

Execution Errors

"Workflow did not finish"

Causes:

  1. Infinite Loop

    • Missing stop condition in loop
    • Always include maximum iterations
  2. Timeout

    • Workflow taking too long
    • Default timeout might be exceeded
    • Optimize or increase timeout settings

"Missing node parameter"

Cause: Required field is empty or expression evaluates to empty

Solutions:

// Provide default values
{{ $json.email || 'noreply@example.com' }}

// Validate before using
{{ $json.userId ? $json.userId : 'default-id' }}

// Use IF node to branch based on data availability
IF node: {{ $json.email !== undefined && $json.email !== '' }}
   True: Continue with email
   False: Skip or use default

Workflow Executes Multiple Times

Causes:

  1. Trigger Firing Multiple Times
    • Webhook called multiple times by external service
    • Schedule trigger overlapping with long execution
    • Email trigger processing same email multiple times

Solutions:

  • Add deduplication logic
  • Use IF node to check if already processed
  • Store processed IDs in database
  • Adjust trigger settings (e.g., mark emails as read)

Node-Specific Issues

Code Node Issues

"items is not defined"

// Wrong: Using old syntax
for (item of items) { }

// Correct: Access items array
for (const item of items) { }

// Or use functional approach
return items.map(item => ({
  json: {
    // transformed data
  }
}));

"Must return array"

// Wrong: Returning object
return { json: { value: 123 } };

// Correct: Return array of items
return [{ json: { value: 123 } }];

// Multiple items
return [
  { json: { id: 1 } },
  { json: { id: 2 } }
];

Set Node Issues

"Expression error in field"

  • Check expression syntax
  • Verify referenced node names
  • Test expression in expression editor
  • Use debug panel to see available data

IF Node Issues

"All items ending up in one branch"

  • Verify condition logic
  • Check data types (string vs number)
  • Use debug panel to see actual values
  • Test condition in expression editor

Split In Batches Issues

"Loop not completing"

  • Ensure "Loop Over Items" is connected back to Split In Batches
  • Verify batch size is appropriate
  • Check for errors in loop that stop execution

General Debugging Tips

  1. Use Debug Panel

    • Click on node to see input/output
    • Inspect data structure before writing expressions
    • Check for null/undefined values
  2. Test Incrementally

    • Build workflow step by step
    • Test each node before adding next
    • Use "Execute Node" to test individual nodes
  3. Add Logging

    // In Code node
    console.log('Debug info:', items[0].json);
    // View in execution logs
    
  4. Use Set Nodes for Debugging

    // Add Set node with debug fields
    debug_field: {{ $json }}
    debug_type: {{ typeof $json.value }}
    debug_length: {{ $json.items?.length }}
    
  5. Check Execution Logs

    • View past executions
    • Look for error messages
    • Compare successful vs failed runs
  6. Simplify

    • Remove complex expressions temporarily
    • Use static values to isolate issues
    • Test with minimal data first
  7. Read Error Messages Carefully

    • Error often points to exact issue
    • Note line numbers in Code nodes
    • Google specific error messages

Getting Help

If you're still stuck:

  1. Check n8n Documentation

  2. Community Forum

  3. GitHub Issues

  4. Export Workflow

    • Download as JSON for sharing
    • Remove sensitive credentials
    • Include error messages when asking for help

Quick Reference: Common Error Messages

Error Common Cause Solution
401 Unauthorized Wrong credentials Check credential, verify API key
403 Forbidden Insufficient permissions Check API permissions, IP whitelist
404 Not Found Wrong URL/endpoint Verify URL, check API docs
500 Internal Server Error API issue or bad request Check request body, verify API status
Timeout Request too slow Increase timeout, optimize request
Expression error Syntax or missing data Check syntax, verify node names
Cannot read property Undefined value Use optional chaining ?.
Node not found Wrong node name Match exact node name (case-sensitive)
Invalid DateTime Bad date format Validate date before parsing
JavaScript heap out of memory Too much data Process in batches, reduce data size