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

610 lines
15 KiB
Markdown

# n8n Troubleshooting Guide
Common issues and solutions for n8n workflow debugging.
## Table of Contents
- [Authentication Errors](#authentication-errors)
- [Expression Errors](#expression-errors)
- [HTTP Request Errors](#http-request-errors)
- [Webhook Issues](#webhook-issues)
- [Data Transformation Problems](#data-transformation-problems)
- [Performance Issues](#performance-issues)
- [Execution Errors](#execution-errors)
- [Node-Specific Issues](#node-specific-issues)
## 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**
```javascript
// 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:**
```bash
# 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:**
```javascript
// 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:**
```javascript
// 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:**
```javascript
// 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"**
```javascript
// 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**
```javascript
// 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:
```bash
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:**
```javascript
// 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:**
```javascript
// 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:**
```javascript
// 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**
```javascript
// 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:**
```javascript
// 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"**
```javascript
// 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"**
```javascript
// 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**
```javascript
// In Code node
console.log('Debug info:', items[0].json);
// View in execution logs
```
4. **Use Set Nodes for Debugging**
```javascript
// 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**
- https://docs.n8n.io/
- Node-specific docs
- Expression reference
2. **Community Forum**
- https://community.n8n.io/
- Search for similar issues
- Post workflow JSON for help
3. **GitHub Issues**
- https://github.com/n8n-io/n8n
- Report bugs
- Check known 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 |