Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:17:17 +08:00
commit 6062d3994e
39 changed files with 21748 additions and 0 deletions

View File

@@ -0,0 +1,943 @@
# Error Catalog
Comprehensive catalog of n8n validation errors with real examples and fixes.
---
## Error Types Overview
Common validation errors by priority:
| Error Type | Priority | Severity | Auto-Fix |
|---|---|---|---|
| missing_required | Highest | Error | ❌ |
| invalid_value | High | Error | ❌ |
| type_mismatch | Medium | Error | ❌ |
| invalid_expression | Medium | Error | ❌ |
| invalid_reference | Low | Error | ❌ |
| operator_structure | Lowest | Warning | ✅ |
---
## Errors (Must Fix)
### 1. missing_required
**What it means**: Required field is not provided in node configuration
**When it occurs**:
- Creating new nodes without all required fields
- Copying configurations between different operations
- Switching operations that have different requirements
**Most common validation error**
#### Example 1: Slack Channel Missing
**Error**:
```json
{
"type": "missing_required",
"property": "channel",
"message": "Channel name is required",
"node": "Slack",
"path": "parameters.channel"
}
```
**Broken Configuration**:
```javascript
{
"resource": "message",
"operation": "post"
// Missing: channel
}
```
**Fix**:
```javascript
{
"resource": "message",
"operation": "post",
"channel": "#general" // ✅ Added required field
}
```
**How to identify required fields**:
```javascript
// Use get_node_essentials to see what's required
const info = get_node_essentials({
nodeType: "nodes-base.slack"
});
// Check properties marked as "required": true
```
#### Example 2: HTTP Request Missing URL
**Error**:
```json
{
"type": "missing_required",
"property": "url",
"message": "URL is required for HTTP Request",
"node": "HTTP Request",
"path": "parameters.url"
}
```
**Broken Configuration**:
```javascript
{
"method": "GET",
"authentication": "none"
// Missing: url
}
```
**Fix**:
```javascript
{
"method": "GET",
"authentication": "none",
"url": "https://api.example.com/data" // ✅ Added
}
```
#### Example 3: Database Query Missing Connection
**Error**:
```json
{
"type": "missing_required",
"property": "query",
"message": "SQL query is required",
"node": "Postgres",
"path": "parameters.query"
}
```
**Broken Configuration**:
```javascript
{
"operation": "executeQuery"
// Missing: query
}
```
**Fix**:
```javascript
{
"operation": "executeQuery",
"query": "SELECT * FROM users WHERE active = true" // ✅ Added
}
```
#### Example 4: Conditional Fields
**Error**:
```json
{
"type": "missing_required",
"property": "body",
"message": "Request body is required when sendBody is true",
"node": "HTTP Request",
"path": "parameters.body"
}
```
**Broken Configuration**:
```javascript
{
"method": "POST",
"url": "https://api.example.com/create",
"sendBody": true
// Missing: body (required when sendBody=true)
}
```
**Fix**:
```javascript
{
"method": "POST",
"url": "https://api.example.com/create",
"sendBody": true,
"body": {
"contentType": "json",
"content": {
"name": "John",
"email": "john@example.com"
}
} // ✅ Added conditional required field
}
```
---
### 2. invalid_value
**What it means**: Provided value doesn't match allowed options or format
**When it occurs**:
- Using wrong enum value
- Typos in operation names
- Invalid format for specialized fields (emails, URLs, channels)
**Second most common error**
#### Example 1: Invalid Operation
**Error**:
```json
{
"type": "invalid_value",
"property": "operation",
"message": "Operation must be one of: post, update, delete, get",
"current": "send",
"allowed": ["post", "update", "delete", "get"]
}
```
**Broken Configuration**:
```javascript
{
"resource": "message",
"operation": "send" // ❌ Invalid - should be "post"
}
```
**Fix**:
```javascript
{
"resource": "message",
"operation": "post" // ✅ Use valid operation
}
```
#### Example 2: Invalid HTTP Method
**Error**:
```json
{
"type": "invalid_value",
"property": "method",
"message": "Method must be one of: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS",
"current": "FETCH",
"allowed": ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]
}
```
**Broken Configuration**:
```javascript
{
"method": "FETCH", // ❌ Invalid
"url": "https://api.example.com"
}
```
**Fix**:
```javascript
{
"method": "GET", // ✅ Use valid HTTP method
"url": "https://api.example.com"
}
```
#### Example 3: Invalid Channel Format
**Error**:
```json
{
"type": "invalid_value",
"property": "channel",
"message": "Channel name must start with # and be lowercase (e.g., #general)",
"current": "General"
}
```
**Broken Configuration**:
```javascript
{
"resource": "message",
"operation": "post",
"channel": "General" // ❌ Wrong format
}
```
**Fix**:
```javascript
{
"resource": "message",
"operation": "post",
"channel": "#general" // ✅ Correct format
}
```
#### Example 4: Invalid Enum with Case Sensitivity
**Error**:
```json
{
"type": "invalid_value",
"property": "resource",
"message": "Resource must be one of: channel, message, user, file",
"current": "Message",
"allowed": ["channel", "message", "user", "file"]
}
```
**Note**: Enums are case-sensitive!
**Broken Configuration**:
```javascript
{
"resource": "Message", // ❌ Capital M
"operation": "post"
}
```
**Fix**:
```javascript
{
"resource": "message", // ✅ Lowercase
"operation": "post"
}
```
---
### 3. type_mismatch
**What it means**: Value is wrong data type (string instead of number, etc.)
**When it occurs**:
- Hardcoding values that should be numbers
- Using expressions where literals are expected
- JSON serialization issues
**Common error**
#### Example 1: String Instead of Number
**Error**:
```json
{
"type": "type_mismatch",
"property": "limit",
"message": "Expected number, got string",
"expected": "number",
"current": "100"
}
```
**Broken Configuration**:
```javascript
{
"operation": "executeQuery",
"query": "SELECT * FROM users",
"limit": "100" // ❌ String
}
```
**Fix**:
```javascript
{
"operation": "executeQuery",
"query": "SELECT * FROM users",
"limit": 100 // ✅ Number
}
```
#### Example 2: Number Instead of String
**Error**:
```json
{
"type": "type_mismatch",
"property": "channel",
"message": "Expected string, got number",
"expected": "string",
"current": 12345
}
```
**Broken Configuration**:
```javascript
{
"resource": "message",
"operation": "post",
"channel": 12345 // ❌ Number (even if channel ID)
}
```
**Fix**:
```javascript
{
"resource": "message",
"operation": "post",
"channel": "#general" // ✅ String (channel name, not ID)
}
```
#### Example 3: Boolean as String
**Error**:
```json
{
"type": "type_mismatch",
"property": "sendHeaders",
"message": "Expected boolean, got string",
"expected": "boolean",
"current": "true"
}
```
**Broken Configuration**:
```javascript
{
"method": "GET",
"url": "https://api.example.com",
"sendHeaders": "true" // ❌ String "true"
}
```
**Fix**:
```javascript
{
"method": "GET",
"url": "https://api.example.com",
"sendHeaders": true // ✅ Boolean true
}
```
#### Example 4: Object Instead of Array
**Error**:
```json
{
"type": "type_mismatch",
"property": "tags",
"message": "Expected array, got object",
"expected": "array",
"current": {"tag": "important"}
}
```
**Broken Configuration**:
```javascript
{
"name": "New Channel",
"tags": {"tag": "important"} // ❌ Object
}
```
**Fix**:
```javascript
{
"name": "New Channel",
"tags": ["important", "alerts"] // ✅ Array
}
```
---
### 4. invalid_expression
**What it means**: n8n expression has syntax errors or invalid references
**When it occurs**:
- Missing `{{}}` around expressions
- Typos in variable names
- Referencing non-existent nodes or fields
- Invalid JavaScript syntax in expressions
**Moderately common**
**Related**: See **n8n Expression Syntax** skill for comprehensive expression guidance
#### Example 1: Missing Curly Braces
**Error**:
```json
{
"type": "invalid_expression",
"property": "text",
"message": "Expressions must be wrapped in {{}}",
"current": "$json.name"
}
```
**Broken Configuration**:
```javascript
{
"resource": "message",
"operation": "post",
"channel": "#general",
"text": "$json.name" // ❌ Missing {{}}
}
```
**Fix**:
```javascript
{
"resource": "message",
"operation": "post",
"channel": "#general",
"text": "={{$json.name}}" // ✅ Wrapped in {{}}
}
```
#### Example 2: Invalid Node Reference
**Error**:
```json
{
"type": "invalid_expression",
"property": "value",
"message": "Referenced node 'HTTP Requets' does not exist",
"current": "={{$node['HTTP Requets'].json.data}}"
}
```
**Broken Configuration**:
```javascript
{
"field": "data",
"value": "={{$node['HTTP Requets'].json.data}}" // ❌ Typo in node name
}
```
**Fix**:
```javascript
{
"field": "data",
"value": "={{$node['HTTP Request'].json.data}}" // ✅ Correct node name
}
```
#### Example 3: Invalid Property Access
**Error**:
```json
{
"type": "invalid_expression",
"property": "text",
"message": "Cannot access property 'user' of undefined",
"current": "={{$json.data.user.name}}"
}
```
**Broken Configuration**:
```javascript
{
"text": "={{$json.data.user.name}}" // ❌ Structure doesn't exist
}
```
**Fix** (with safe navigation):
```javascript
{
"text": "={{$json.data?.user?.name || 'Unknown'}}" // ✅ Safe navigation + fallback
}
```
#### Example 4: Webhook Data Access Error
**Error**:
```json
{
"type": "invalid_expression",
"property": "value",
"message": "Property 'email' not found in $json",
"current": "={{$json.email}}"
}
```
**Common Gotcha**: Webhook data is under `.body`!
**Broken Configuration**:
```javascript
{
"field": "email",
"value": "={{$json.email}}" // ❌ Missing .body
}
```
**Fix**:
```javascript
{
"field": "email",
"value": "={{$json.body.email}}" // ✅ Webhook data under .body
}
```
---
### 5. invalid_reference
**What it means**: Configuration references a node that doesn't exist in the workflow
**When it occurs**:
- Node was renamed or deleted
- Typo in node name
- Copy-pasting from another workflow
**Less common error**
#### Example 1: Deleted Node Reference
**Error**:
```json
{
"type": "invalid_reference",
"property": "expression",
"message": "Node 'Transform Data' does not exist in workflow",
"referenced_node": "Transform Data"
}
```
**Broken Configuration**:
```javascript
{
"value": "={{$node['Transform Data'].json.result}}" // ❌ Node deleted
}
```
**Fix**:
```javascript
// Option 1: Update to existing node
{
"value": "={{$node['Set'].json.result}}"
}
// Option 2: Remove expression if not needed
{
"value": "default_value"
}
```
#### Example 2: Connection to Non-Existent Node
**Error**:
```json
{
"type": "invalid_reference",
"message": "Connection references node 'Slack1' which does not exist",
"source": "HTTP Request",
"target": "Slack1"
}
```
**Fix**: Use `cleanStaleConnections` operation:
```javascript
n8n_update_partial_workflow({
id: "workflow-id",
operations: [{
type: "cleanStaleConnections"
}]
})
```
#### Example 3: Renamed Node Not Updated
**Error**:
```json
{
"type": "invalid_reference",
"property": "expression",
"message": "Node 'Get Weather' does not exist (did you mean 'Weather API'?)",
"referenced_node": "Get Weather",
"suggestions": ["Weather API"]
}
```
**Broken Configuration**:
```javascript
{
"value": "={{$node['Get Weather'].json.temperature}}" // ❌ Old name
}
```
**Fix**:
```javascript
{
"value": "={{$node['Weather API'].json.temperature}}" // ✅ Current name
}
```
---
## Warnings (Should Fix)
### 6. best_practice
**What it means**: Configuration works but doesn't follow best practices
**Severity**: Warning (doesn't block execution)
**When acceptable**: Development, testing, simple workflows
**When to fix**: Production workflows, critical operations
#### Example 1: Missing Error Handling
**Warning**:
```json
{
"type": "best_practice",
"property": "onError",
"message": "Slack API can have rate limits and connection issues",
"suggestion": "Add error handling: onError: 'continueRegularOutput'"
}
```
**Current Configuration**:
```javascript
{
"resource": "message",
"operation": "post",
"channel": "#alerts"
// No error handling ⚠️
}
```
**Recommended Fix**:
```javascript
{
"resource": "message",
"operation": "post",
"channel": "#alerts",
"continueOnFail": true,
"retryOnFail": true,
"maxTries": 3
}
```
#### Example 2: No Retry Logic
**Warning**:
```json
{
"type": "best_practice",
"property": "retryOnFail",
"message": "External API calls should retry on failure",
"suggestion": "Add retryOnFail: true, maxTries: 3, waitBetweenTries: 1000"
}
```
**When to ignore**: Idempotent operations, APIs with their own retry logic
**When to fix**: Flaky external services, production automation
---
### 7. deprecated
**What it means**: Using old API version or deprecated feature
**Severity**: Warning (still works but may stop working in future)
**When to fix**: Always (eventually)
#### Example 1: Old typeVersion
**Warning**:
```json
{
"type": "deprecated",
"property": "typeVersion",
"message": "typeVersion 1 is deprecated for Slack node, use version 2",
"current": 1,
"recommended": 2
}
```
**Fix**:
```javascript
{
"type": "n8n-nodes-base.slack",
"typeVersion": 2, // ✅ Updated
// May need to update configuration for new version
}
```
---
### 8. performance
**What it means**: Configuration may cause performance issues
**Severity**: Warning
**When to fix**: High-volume workflows, large datasets
#### Example 1: Unbounded Query
**Warning**:
```json
{
"type": "performance",
"property": "query",
"message": "SELECT without LIMIT can return massive datasets",
"suggestion": "Add LIMIT clause or use pagination"
}
```
**Current**:
```sql
SELECT * FROM users WHERE active = true
```
**Fix**:
```sql
SELECT * FROM users WHERE active = true LIMIT 1000
```
---
## Auto-Sanitization Fixes
### 9. operator_structure
**What it means**: IF/Switch operator structure issues
**Severity**: Warning
**Auto-Fix**: ✅ YES - Fixed automatically on workflow save
**Rare** (mostly auto-fixed)
#### Fixed Automatically: Binary Operators
**Before** (you create this):
```javascript
{
"type": "boolean",
"operation": "equals",
"singleValue": true // ❌ Wrong for binary operator
}
```
**After** (auto-sanitization fixes it):
```javascript
{
"type": "boolean",
"operation": "equals"
// singleValue removed ✅
}
```
**You don't need to do anything** - this is fixed on save!
#### Fixed Automatically: Unary Operators
**Before**:
```javascript
{
"type": "boolean",
"operation": "isEmpty"
// Missing singleValue ❌
}
```
**After**:
```javascript
{
"type": "boolean",
"operation": "isEmpty",
"singleValue": true // ✅ Added automatically
}
```
**What you should do**: Trust auto-sanitization, don't manually fix these!
---
## Recovery Patterns
### Pattern 1: Progressive Validation
**Problem**: Too many errors at once
**Solution**:
```javascript
// Step 1: Minimal valid config
let config = {
resource: "message",
operation: "post",
channel: "#general",
text: "Hello"
};
validate_node_operation({nodeType: "nodes-base.slack", config});
// ✅ Valid
// Step 2: Add features one by one
config.attachments = [...];
validate_node_operation({nodeType: "nodes-base.slack", config});
config.blocks = [...];
validate_node_operation({nodeType: "nodes-base.slack", config});
```
### Pattern 2: Error Triage
**Problem**: Multiple errors
**Solution**:
```javascript
const result = validate_node_operation({...});
// 1. Fix errors (must fix)
result.errors.forEach(error => {
console.log(`MUST FIX: ${error.property} - ${error.message}`);
});
// 2. Review warnings (should fix)
result.warnings.forEach(warning => {
console.log(`SHOULD FIX: ${warning.property} - ${warning.message}`);
});
// 3. Consider suggestions (optional)
result.suggestions.forEach(sug => {
console.log(`OPTIONAL: ${sug.message}`);
});
```
### Pattern 3: Use get_node_essentials
**Problem**: Don't know what's required
**Solution**:
```javascript
// Before configuring, check requirements
const info = get_node_essentials({
nodeType: "nodes-base.slack"
});
// Look for required fields
info.properties.forEach(prop => {
if (prop.required) {
console.log(`Required: ${prop.name} (${prop.type})`);
}
});
```
---
## Summary
**Most Common Errors**:
1. `missing_required` (45%) - Always check get_node_essentials
2. `invalid_value` (28%) - Check allowed values
3. `type_mismatch` (12%) - Use correct data types
4. `invalid_expression` (8%) - Use Expression Syntax skill
5. `invalid_reference` (5%) - Clean stale connections
**Auto-Fixed**:
- `operator_structure` - Trust auto-sanitization!
**Related Skills**:
- **[SKILL.md](SKILL.md)** - Main validation guide
- **[FALSE_POSITIVES.md](FALSE_POSITIVES.md)** - When to ignore warnings
- **n8n Expression Syntax** - Fix expression errors
- **n8n MCP Tools Expert** - Use validation tools correctly

View File

@@ -0,0 +1,720 @@
# False Positives Guide
When validation warnings are acceptable and how to handle them.
---
## What Are False Positives?
**Definition**: Validation warnings that are technically "issues" but acceptable in your specific use case.
**Key insight**: Not all warnings need to be fixed!
Many warnings are context-dependent:
- ~40% of warnings are acceptable in specific use cases
- Using `ai-friendly` profile reduces false positives by 60%
---
## Philosophy
### ✅ Good Practice
```
1. Run validation with 'runtime' profile
2. Fix all ERRORS
3. Review each WARNING
4. Decide if acceptable for your use case
5. Document why you accepted it
6. Deploy with confidence
```
### ❌ Bad Practice
```
1. Ignore all warnings blindly
2. Use 'minimal' profile to avoid warnings
3. Deploy without understanding risks
```
---
## Common False Positives
### 1. Missing Error Handling
**Warning**:
```json
{
"type": "best_practice",
"message": "No error handling configured",
"suggestion": "Add continueOnFail: true and retryOnFail: true"
}
```
#### When Acceptable
**✅ Development/Testing Workflows**
```javascript
// Testing workflow - failures are obvious
{
"name": "Test Slack Integration",
"nodes": [{
"type": "n8n-nodes-base.slack",
"parameters": {
"resource": "message",
"operation": "post",
"channel": "#test"
// No error handling - OK for testing
}
}]
}
```
**Reasoning**: You WANT to see failures during testing.
**✅ Non-Critical Notifications**
```javascript
// Nice-to-have notification
{
"name": "Optional Slack Notification",
"parameters": {
"channel": "#general",
"text": "FYI: Process completed"
// If this fails, no big deal
}
}
```
**Reasoning**: Notification failure doesn't affect core functionality.
**✅ Manual Trigger Workflows**
```javascript
// Manual workflow - user is watching
{
"nodes": [{
"type": "n8n-nodes-base.webhook",
"parameters": {
"path": "manual-test"
// No error handling - user will retry manually
}
}]
}
```
**Reasoning**: User is present to see and handle errors.
#### When to Fix
**❌ Production Automation**
```javascript
// BAD: Critical workflow without error handling
{
"name": "Process Customer Orders",
"nodes": [{
"type": "n8n-nodes-base.postgres",
"parameters": {
"query": "INSERT INTO orders..."
// ❌ Should have error handling!
}
}]
}
```
**Fix**:
```javascript
{
"parameters": {
"query": "INSERT INTO orders...",
"continueOnFail": true,
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 1000
}
}
```
**❌ Critical Integrations**
```javascript
// BAD: Payment processing without error handling
{
"name": "Process Payment",
"type": "n8n-nodes-base.stripe"
// ❌ Payment failures MUST be handled!
}
```
---
### 2. No Retry Logic
**Warning**:
```json
{
"type": "best_practice",
"message": "External API calls should retry on failure",
"suggestion": "Add retryOnFail: true with exponential backoff"
}
```
#### When Acceptable
**✅ APIs with Built-in Retry**
```javascript
// Stripe has its own retry mechanism
{
"type": "n8n-nodes-base.stripe",
"parameters": {
"resource": "charge",
"operation": "create"
// Stripe SDK retries automatically
}
}
```
**✅ Idempotent Operations**
```javascript
// GET request - safe to retry manually if needed
{
"method": "GET",
"url": "https://api.example.com/status"
// Read-only, no side effects
}
```
**✅ Local/Internal Services**
```javascript
// Internal API with high reliability
{
"url": "http://localhost:3000/process"
// Local service, failures are rare and obvious
}
```
#### When to Fix
**❌ Flaky External APIs**
```javascript
// BAD: Known unreliable API without retries
{
"url": "https://unreliable-api.com/data"
// ❌ Should retry!
}
// GOOD:
{
"url": "https://unreliable-api.com/data",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2000
}
```
**❌ Non-Idempotent Operations**
```javascript
// BAD: POST without retry - may lose data
{
"method": "POST",
"url": "https://api.example.com/create"
// ❌ Could timeout and lose data
}
```
---
### 3. Missing Rate Limiting
**Warning**:
```json
{
"type": "best_practice",
"message": "API may have rate limits",
"suggestion": "Add rate limiting or batch requests"
}
```
#### When Acceptable
**✅ Internal APIs**
```javascript
// Internal microservice - no rate limits
{
"url": "http://internal-api/process"
// Company controls both ends
}
```
**✅ Low-Volume Workflows**
```javascript
// Runs once per day
{
"trigger": {
"type": "n8n-nodes-base.cron",
"parameters": {
"mode": "everyDay",
"hour": 9
}
},
"nodes": [{
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.example.com/daily-report"
// Once per day = no rate limit concerns
}
}]
}
```
**✅ APIs with Server-Side Limits**
```javascript
// API returns 429 and n8n handles it
{
"url": "https://api.example.com/data",
"options": {
"response": {
"response": {
"neverError": false // Will error on 429
}
}
},
"retryOnFail": true // Retry on 429
}
```
#### When to Fix
**❌ High-Volume Public APIs**
```javascript
// BAD: Loop hitting rate-limited API
{
"nodes": [{
"type": "n8n-nodes-base.splitInBatches",
"parameters": {
"batchSize": 100
}
}, {
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.github.com/..."
// ❌ GitHub has strict rate limits!
}
}]
}
// GOOD: Add rate limiting
{
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.github.com/...",
"options": {
"batching": {
"batch": {
"batchSize": 10,
"batchInterval": 1000 // 1 second between batches
}
}
}
}
}
```
---
### 4. Unbounded Database Queries
**Warning**:
```json
{
"type": "performance",
"message": "SELECT without LIMIT can return massive datasets",
"suggestion": "Add LIMIT clause or use pagination"
}
```
#### When Acceptable
**✅ Small Known Datasets**
```javascript
// Config table with ~10 rows
{
"query": "SELECT * FROM app_config"
// Known to be small, no LIMIT needed
}
```
**✅ Aggregation Queries**
```javascript
// COUNT/SUM operations
{
"query": "SELECT COUNT(*) as total FROM users WHERE active = true"
// Aggregation, not returning rows
}
```
**✅ Development/Testing**
```javascript
// Testing with small dataset
{
"query": "SELECT * FROM test_users"
// Test database has 5 rows
}
```
#### When to Fix
**❌ Production Queries on Large Tables**
```javascript
// BAD: User table could have millions of rows
{
"query": "SELECT * FROM users"
// ❌ Could return millions of rows!
}
// GOOD: Add LIMIT
{
"query": "SELECT * FROM users LIMIT 1000"
}
// BETTER: Use pagination
{
"query": "SELECT * FROM users WHERE id > {{$json.lastId}} LIMIT 1000"
}
```
---
### 5. Missing Input Validation
**Warning**:
```json
{
"type": "best_practice",
"message": "Webhook doesn't validate input data",
"suggestion": "Add IF node to validate required fields"
}
```
#### When Acceptable
**✅ Internal Webhooks**
```javascript
// Webhook from your own backend
{
"type": "n8n-nodes-base.webhook",
"parameters": {
"path": "internal-trigger"
// Your backend already validates
}
}
```
**✅ Trusted Sources**
```javascript
// Webhook from Stripe (cryptographically signed)
{
"type": "n8n-nodes-base.webhook",
"parameters": {
"path": "stripe-webhook",
"authentication": "headerAuth"
// Stripe signature validates authenticity
}
}
```
#### When to Fix
**❌ Public Webhooks**
```javascript
// BAD: Public webhook without validation
{
"type": "n8n-nodes-base.webhook",
"parameters": {
"path": "public-form-submit"
// ❌ Anyone can send anything!
}
}
// GOOD: Add validation
{
"nodes": [
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook"
},
{
"name": "Validate Input",
"type": "n8n-nodes-base.if",
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json.body.email}}",
"operation": "isNotEmpty"
},
{
"value1": "={{$json.body.email}}",
"operation": "regex",
"value2": "^[^@]+@[^@]+\\.[^@]+$"
}
]
}
}
}
]
}
```
---
### 6. Hardcoded Credentials
**Warning**:
```json
{
"type": "security",
"message": "Credentials should not be hardcoded",
"suggestion": "Use n8n credential system"
}
```
#### When Acceptable
**✅ Public APIs (No Auth)**
```javascript
// Truly public API with no secrets
{
"url": "https://api.ipify.org"
// No credentials needed
}
```
**✅ Demo/Example Workflows**
```javascript
// Example workflow in documentation
{
"url": "https://example.com/api",
"headers": {
"Authorization": "Bearer DEMO_TOKEN"
}
// Clearly marked as example
}
```
#### When to Fix (Always!)
**❌ Real Credentials**
```javascript
// BAD: Real API key in workflow
{
"headers": {
"Authorization": "Bearer sk_live_abc123..."
}
// ❌ NEVER hardcode real credentials!
}
// GOOD: Use credentials system
{
"authentication": "headerAuth",
"credentials": {
"headerAuth": {
"id": "credential-id",
"name": "My API Key"
}
}
}
```
---
## Validation Profile Strategies
### Strategy 1: Progressive Strictness
**Development**:
```javascript
validate_node_operation({
nodeType: "nodes-base.slack",
config,
profile: "ai-friendly" // Fewer warnings during development
})
```
**Pre-Production**:
```javascript
validate_node_operation({
nodeType: "nodes-base.slack",
config,
profile: "runtime" // Balanced validation
})
```
**Production Deployment**:
```javascript
validate_node_operation({
nodeType: "nodes-base.slack",
config,
profile: "strict" // All warnings, review each one
})
```
### Strategy 2: Profile by Workflow Type
**Quick Automations**:
- Profile: `ai-friendly`
- Accept: Most warnings
- Fix: Only errors + security warnings
**Business-Critical Workflows**:
- Profile: `strict`
- Accept: Very few warnings
- Fix: Everything possible
**Integration Testing**:
- Profile: `minimal`
- Accept: All warnings (just testing connections)
- Fix: Only errors that prevent execution
---
## Decision Framework
### Should I Fix This Warning?
```
┌─────────────────────────────────┐
│ Is it a SECURITY warning? │
├─────────────────────────────────┤
│ YES → Always fix │
│ NO → Continue │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ Is this a production workflow? │
├─────────────────────────────────┤
│ YES → Continue │
│ NO → Probably acceptable │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ Does it handle critical data? │
├─────────────────────────────────┤
│ YES → Fix the warning │
│ NO → Continue │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ Is there a known workaround? │
├─────────────────────────────────┤
│ YES → Acceptable if documented │
│ NO → Fix the warning │
└─────────────────────────────────┘
```
---
## Documentation Template
When accepting a warning, document why:
```javascript
// workflows/customer-notifications.json
{
"nodes": [{
"name": "Send Slack Notification",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "#notifications"
// ACCEPTED WARNING: No error handling
// Reason: Non-critical notification, failures are acceptable
// Reviewed: 2025-10-20
// Reviewer: Engineering Team
}
}]
}
```
---
## Known n8n Issues
### Issue #304: IF Node Metadata Warning
**Warning**:
```json
{
"type": "metadata_incomplete",
"message": "IF node missing conditions.options metadata",
"node": "IF"
}
```
**Status**: False positive for IF v2.2+
**Why it occurs**: Auto-sanitization adds metadata, but validation runs before sanitization
**What to do**: Ignore - metadata is added on save
### Issue #306: Switch Branch Count
**Warning**:
```json
{
"type": "configuration_mismatch",
"message": "Switch has 3 rules but 4 output connections",
"node": "Switch"
}
```
**Status**: False positive when using "fallback" mode
**Why it occurs**: Fallback creates extra output
**What to do**: Ignore if using fallback intentionally
### Issue #338: Credential Validation in Test Mode
**Warning**:
```json
{
"type": "credentials_invalid",
"message": "Cannot validate credentials without execution context"
}
```
**Status**: False positive during static validation
**Why it occurs**: Credentials validated at runtime, not build time
**What to do**: Ignore - credentials are validated when workflow runs
---
## Summary
### Always Fix
- ❌ Security warnings
- ❌ Hardcoded credentials
- ❌ SQL injection risks
- ❌ Production workflow errors
### Usually Fix
- ⚠️ Error handling (production)
- ⚠️ Retry logic (external APIs)
- ⚠️ Input validation (public webhooks)
- ⚠️ Rate limiting (high volume)
### Often Acceptable
- ✅ Error handling (dev/test)
- ✅ Retry logic (internal APIs)
- ✅ Rate limiting (low volume)
- ✅ Query limits (small datasets)
### Always Acceptable
- ✅ Known n8n issues (#304, #306, #338)
- ✅ Auto-sanitization warnings
- ✅ Metadata completeness (auto-fixed)
**Golden Rule**: If you accept a warning, document WHY.
**Related Files**:
- **[SKILL.md](SKILL.md)** - Main validation guide
- **[ERROR_CATALOG.md](ERROR_CATALOG.md)** - Error types and fixes

View File

@@ -0,0 +1,290 @@
# n8n Validation Expert
Expert guidance for interpreting and fixing n8n validation errors.
## Overview
**Skill Name**: n8n Validation Expert
**Priority**: Medium
**Purpose**: Interpret validation errors and guide systematic fixing through the validation loop
## The Problem This Solves
Validation errors are common:
- Validation often requires iteration (79% lead to feedback loops)
- **7,841 validate → fix cycles** (avg 23s thinking + 58s fixing)
- **2-3 iterations** average to achieve valid configuration
**Key insight**: Validation is an iterative process, not a one-shot fix!
## What This Skill Teaches
### Core Concepts
1. **Error Severity Levels**
- Errors (must fix) - Block execution
- Warnings (should fix) - Don't block but indicate issues
- Suggestions (optional) - Nice-to-have improvements
2. **The Validation Loop**
- Configure → Validate → Read errors → Fix → Validate again
- Average 2-3 iterations to success
- 23 seconds thinking + 58 seconds fixing per cycle
3. **Validation Profiles**
- `minimal` - Quick checks, most permissive
- `runtime` - Recommended for most use cases
- `ai-friendly` - Reduces false positives for AI workflows
- `strict` - Maximum safety, many warnings
4. **Auto-Sanitization System**
- Automatically fixes operator structure issues
- Runs on every workflow save
- Fixes binary/unary operator problems
- Adds IF/Switch metadata
5. **False Positives**
- Not all warnings need fixing
- 40% of warnings are acceptable in context
- Use `ai-friendly` profile to reduce by 60%
- Document accepted warnings
## File Structure
```
n8n-validation-expert/
├── SKILL.md (690 lines)
│ Core validation concepts and workflow
│ - Validation philosophy
│ - Error severity levels
│ - The validation loop pattern
│ - Validation profiles
│ - Common error types
│ - Auto-sanitization system
│ - Workflow validation
│ - Recovery strategies
│ - Best practices
├── ERROR_CATALOG.md (865 lines)
│ Complete error reference with examples
│ - 9 error types with real examples
│ - missing_required (45% of errors)
│ - invalid_value (28%)
│ - type_mismatch (12%)
│ - invalid_expression (8%)
│ - invalid_reference (5%)
│ - operator_structure (2%, auto-fixed)
│ - Recovery patterns
│ - Summary with frequencies
├── FALSE_POSITIVES.md (669 lines)
│ When warnings are acceptable
│ - Philosophy of warning acceptance
│ - 6 common false positive types
│ - When acceptable vs when to fix
│ - Validation profile strategies
│ - Decision framework
│ - Documentation template
│ - Known n8n issues (#304, #306, #338)
└── README.md (this file)
Skill metadata and statistics
```
**Total**: ~2,224 lines across 4 files
## Common Error Types
| Error Type | Priority | Auto-Fix | Severity |
|---|---|---|---|
| missing_required | Highest | ❌ | Error |
| invalid_value | High | ❌ | Error |
| type_mismatch | Medium | ❌ | Error |
| invalid_expression | Medium | ❌ | Error |
| invalid_reference | Low | ❌ | Error |
| operator_structure | Low | ✅ | Warning |
## Key Insights
### 1. Validation is Iterative
Don't expect to get it right on the first try. Multiple validation cycles (typically 2-3) are normal and expected!
### 2. False Positives Exist
Many validation warnings are acceptable in production workflows. This skill helps you recognize which ones to address vs. which to ignore.
### 3. Auto-Sanitization Works
Certain error types (like operator structure issues) are automatically fixed by n8n. Don't waste time manually fixing these!
### 4. Profile Matters
- `ai-friendly` reduces false positives by 60%
- `runtime` is the sweet spot for most use cases
- `strict` has value pre-production but is noisy
### 5. Error Messages Help
Validation errors include fix guidance - read them carefully!
## Usage Examples
### Example 1: Basic Validation Loop
```javascript
// Iteration 1
let config = {
resource: "channel",
operation: "create"
};
const result1 = validate_node_operation({
nodeType: "nodes-base.slack",
config,
profile: "runtime"
});
// → Error: Missing "name"
// Iteration 2
config.name = "general";
const result2 = validate_node_operation({...});
// → Valid! ✅
```
### Example 2: Handling False Positives
```javascript
// Run validation
const result = validate_node_operation({
nodeType: "nodes-base.slack",
config,
profile: "runtime"
});
// Fix errors (must fix)
if (!result.valid) {
result.errors.forEach(error => {
console.log(`MUST FIX: ${error.message}`);
});
}
// Review warnings (context-dependent)
result.warnings.forEach(warning => {
if (warning.type === 'best_practice' && isDevWorkflow) {
console.log(`ACCEPTABLE: ${warning.message}`);
} else {
console.log(`SHOULD FIX: ${warning.message}`);
}
});
```
### Example 3: Using Auto-Fix
```javascript
// Check what can be auto-fixed
const preview = n8n_autofix_workflow({
id: "workflow-id",
applyFixes: false // Preview mode
});
console.log(`Can auto-fix: ${preview.fixCount} issues`);
// Apply fixes
if (preview.fixCount > 0) {
n8n_autofix_workflow({
id: "workflow-id",
applyFixes: true
});
}
```
## When This Skill Activates
**Trigger phrases**:
- "validation error"
- "validation failing"
- "what does this error mean"
- "false positive"
- "validation loop"
- "operator structure"
- "validation profile"
**Common scenarios**:
- Encountering validation errors
- Stuck in validation feedback loops
- Wondering if warnings need fixing
- Choosing the right validation profile
- Understanding auto-sanitization
## Integration with Other Skills
### Works With:
- **n8n MCP Tools Expert** - How to use validation tools correctly
- **n8n Expression Syntax** - Fix invalid_expression errors
- **n8n Node Configuration** - Understand required fields
- **n8n Workflow Patterns** - Validate pattern implementations
### Complementary:
- Use MCP Tools Expert to call validation tools
- Use Expression Syntax to fix expression errors
- Use Node Configuration to understand dependencies
- Use Workflow Patterns to validate structure
## Testing
**Evaluations**: 4 test scenarios
1. **eval-001-missing-required-field.json**
- Tests error interpretation
- Guides to get_node_essentials
- References ERROR_CATALOG.md
2. **eval-002-false-positive.json**
- Tests warning vs error distinction
- Explains false positives
- References FALSE_POSITIVES.md
- Suggests ai-friendly profile
3. **eval-003-auto-sanitization.json**
- Tests auto-sanitization understanding
- Explains operator structure fixes
- Advises trusting auto-fix
4. **eval-004-validation-loop.json**
- Tests iterative validation process
- Explains 2-3 iteration pattern
- Provides systematic approach
## Success Metrics
**Before this skill**:
- Users confused by validation errors
- Multiple failed attempts to fix
- Frustration with "validation loops"
- Fixing issues that auto-fix handles
- Fixing all warnings unnecessarily
**After this skill**:
- Systematic error resolution
- Understanding of iteration process
- Recognition of false positives
- Trust in auto-sanitization
- Context-aware warning handling
- 94% success within 3 iterations
## Related Documentation
- **n8n-mcp MCP Server**: Provides validation tools
- **n8n Validation API**: validate_node_operation, validate_workflow, n8n_autofix_workflow
- **n8n Issues**: #304 (IF metadata), #306 (Switch branches), #338 (credentials)
## Version History
- **v1.0** (2025-10-20): Initial implementation
- SKILL.md with core concepts
- ERROR_CATALOG.md with 9 error types
- FALSE_POSITIVES.md with 6 false positive patterns
- 4 evaluation scenarios
## Author
Conceived by Romuald Członkowski - [www.aiadvisors.pl/en](https://www.aiadvisors.pl/en)
Part of the n8n-skills meta-skill collection.

View File

@@ -0,0 +1,689 @@
---
name: n8n-validation-expert
description: Interpret validation errors and guide fixing them. Use when encountering validation errors, validation warnings, false positives, operator structure issues, or need help understanding validation results. Also use when asking about validation profiles, error types, or the validation loop process.
---
# n8n Validation Expert
Expert guide for interpreting and fixing n8n validation errors.
---
## Validation Philosophy
**Validate early, validate often**
Validation is typically iterative:
- Expect validation feedback loops
- Usually 2-3 validate → fix cycles
- Average: 23s thinking about errors, 58s fixing them
**Key insight**: Validation is an iterative process, not one-shot!
---
## Error Severity Levels
### 1. Errors (Must Fix)
**Blocks workflow execution** - Must be resolved before activation
**Types**:
- `missing_required` - Required field not provided
- `invalid_value` - Value doesn't match allowed options
- `type_mismatch` - Wrong data type (string instead of number)
- `invalid_reference` - Referenced node doesn't exist
- `invalid_expression` - Expression syntax error
**Example**:
```json
{
"type": "missing_required",
"property": "channel",
"message": "Channel name is required",
"fix": "Provide a channel name (lowercase, no spaces, 1-80 characters)"
}
```
### 2. Warnings (Should Fix)
**Doesn't block execution** - Workflow can be activated but may have issues
**Types**:
- `best_practice` - Recommended but not required
- `deprecated` - Using old API/feature
- `performance` - Potential performance issue
**Example**:
```json
{
"type": "best_practice",
"property": "errorHandling",
"message": "Slack API can have rate limits",
"suggestion": "Add onError: 'continueRegularOutput' with retryOnFail"
}
```
### 3. Suggestions (Optional)
**Nice to have** - Improvements that could enhance workflow
**Types**:
- `optimization` - Could be more efficient
- `alternative` - Better way to achieve same result
---
## The Validation Loop
### Pattern from Telemetry
**7,841 occurrences** of this pattern:
```
1. Configure node
2. validate_node_operation (23 seconds thinking about errors)
3. Read error messages carefully
4. Fix errors
5. validate_node_operation again (58 seconds fixing)
6. Repeat until valid (usually 2-3 iterations)
```
### Example
```javascript
// Iteration 1
let config = {
resource: "channel",
operation: "create"
};
const result1 = validate_node_operation({
nodeType: "nodes-base.slack",
config,
profile: "runtime"
});
// → Error: Missing "name"
// ⏱️ 23 seconds thinking...
// Iteration 2
config.name = "general";
const result2 = validate_node_operation({
nodeType: "nodes-base.slack",
config,
profile: "runtime"
});
// → Error: Missing "text"
// ⏱️ 58 seconds fixing...
// Iteration 3
config.text = "Hello!";
const result3 = validate_node_operation({
nodeType: "nodes-base.slack",
config,
profile: "runtime"
});
// → Valid! ✅
```
**This is normal!** Don't be discouraged by multiple iterations.
---
## Validation Profiles
Choose the right profile for your stage:
### minimal
**Use when**: Quick checks during editing
**Validates**:
- Only required fields
- Basic structure
**Pros**: Fastest, most permissive
**Cons**: May miss issues
### runtime (RECOMMENDED)
**Use when**: Pre-deployment validation
**Validates**:
- Required fields
- Value types
- Allowed values
- Basic dependencies
**Pros**: Balanced, catches real errors
**Cons**: Some edge cases missed
**This is the recommended profile for most use cases**
### ai-friendly
**Use when**: AI-generated configurations
**Validates**:
- Same as runtime
- Reduces false positives
- More tolerant of minor issues
**Pros**: Less noisy for AI workflows
**Cons**: May allow some questionable configs
### strict
**Use when**: Production deployment, critical workflows
**Validates**:
- Everything
- Best practices
- Performance concerns
- Security issues
**Pros**: Maximum safety
**Cons**: Many warnings, some false positives
---
## Common Error Types
### 1. missing_required
**What it means**: A required field is not provided
**How to fix**:
1. Use `get_node_essentials` to see required fields
2. Add the missing field to your configuration
3. Provide an appropriate value
**Example**:
```javascript
// Error
{
"type": "missing_required",
"property": "channel",
"message": "Channel name is required"
}
// Fix
config.channel = "#general";
```
### 2. invalid_value
**What it means**: Value doesn't match allowed options
**How to fix**:
1. Check error message for allowed values
2. Use `get_node_essentials` to see options
3. Update to a valid value
**Example**:
```javascript
// Error
{
"type": "invalid_value",
"property": "operation",
"message": "Operation must be one of: post, update, delete",
"current": "send"
}
// Fix
config.operation = "post"; // Use valid operation
```
### 3. type_mismatch
**What it means**: Wrong data type for field
**How to fix**:
1. Check expected type in error message
2. Convert value to correct type
**Example**:
```javascript
// Error
{
"type": "type_mismatch",
"property": "limit",
"message": "Expected number, got string",
"current": "100"
}
// Fix
config.limit = 100; // Number, not string
```
### 4. invalid_expression
**What it means**: Expression syntax error
**How to fix**:
1. Use n8n Expression Syntax skill
2. Check for missing `{{}}` or typos
3. Verify node/field references
**Example**:
```javascript
// Error
{
"type": "invalid_expression",
"property": "text",
"message": "Invalid expression: $json.name",
"current": "$json.name"
}
// Fix
config.text = "={{$json.name}}"; // Add {{}}
```
### 5. invalid_reference
**What it means**: Referenced node doesn't exist
**How to fix**:
1. Check node name spelling
2. Verify node exists in workflow
3. Update reference to correct name
**Example**:
```javascript
// Error
{
"type": "invalid_reference",
"property": "expression",
"message": "Node 'HTTP Requets' does not exist",
"current": "={{$node['HTTP Requets'].json.data}}"
}
// Fix - correct typo
config.expression = "={{$node['HTTP Request'].json.data}}";
```
---
## Auto-Sanitization System
### What It Does
**Automatically fixes common operator structure issues** on ANY workflow update
**Runs when**:
- `n8n_create_workflow`
- `n8n_update_partial_workflow`
- Any workflow save operation
### What It Fixes
#### 1. Binary Operators (Two Values)
**Operators**: equals, notEquals, contains, notContains, greaterThan, lessThan, startsWith, endsWith
**Fix**: Removes `singleValue` property (binary operators compare two values)
**Before**:
```javascript
{
"type": "boolean",
"operation": "equals",
"singleValue": true // ❌ Wrong!
}
```
**After** (automatic):
```javascript
{
"type": "boolean",
"operation": "equals"
// singleValue removed ✅
}
```
#### 2. Unary Operators (One Value)
**Operators**: isEmpty, isNotEmpty, true, false
**Fix**: Adds `singleValue: true` (unary operators check single value)
**Before**:
```javascript
{
"type": "boolean",
"operation": "isEmpty"
// Missing singleValue ❌
}
```
**After** (automatic):
```javascript
{
"type": "boolean",
"operation": "isEmpty",
"singleValue": true // ✅ Added
}
```
#### 3. IF/Switch Metadata
**Fix**: Adds complete `conditions.options` metadata for IF v2.2+ and Switch v3.2+
### What It CANNOT Fix
#### 1. Broken Connections
References to non-existent nodes
**Solution**: Use `cleanStaleConnections` operation in `n8n_update_partial_workflow`
#### 2. Branch Count Mismatches
3 Switch rules but only 2 output connections
**Solution**: Add missing connections or remove extra rules
#### 3. Paradoxical Corrupt States
API returns corrupt data but rejects updates
**Solution**: May require manual database intervention
---
## False Positives
### What Are They?
Validation warnings that are technically "wrong" but acceptable in your use case
### Common False Positives
#### 1. "Missing error handling"
**Warning**: No error handling configured
**When acceptable**:
- Simple workflows where failures are obvious
- Testing/development workflows
- Non-critical notifications
**When to fix**: Production workflows handling important data
#### 2. "No retry logic"
**Warning**: Node doesn't retry on failure
**When acceptable**:
- APIs with their own retry logic
- Idempotent operations
- Manual trigger workflows
**When to fix**: Flaky external services, production automation
#### 3. "Missing rate limiting"
**Warning**: No rate limiting for API calls
**When acceptable**:
- Internal APIs with no limits
- Low-volume workflows
- APIs with server-side rate limiting
**When to fix**: Public APIs, high-volume workflows
#### 4. "Unbounded query"
**Warning**: SELECT without LIMIT
**When acceptable**:
- Small known datasets
- Aggregation queries
- Development/testing
**When to fix**: Production queries on large tables
### Reducing False Positives
**Use `ai-friendly` profile**:
```javascript
validate_node_operation({
nodeType: "nodes-base.slack",
config: {...},
profile: "ai-friendly" // Fewer false positives
})
```
---
## Validation Result Structure
### Complete Response
```javascript
{
"valid": false,
"errors": [
{
"type": "missing_required",
"property": "channel",
"message": "Channel name is required",
"fix": "Provide a channel name (lowercase, no spaces)"
}
],
"warnings": [
{
"type": "best_practice",
"property": "errorHandling",
"message": "Slack API can have rate limits",
"suggestion": "Add onError: 'continueRegularOutput'"
}
],
"suggestions": [
{
"type": "optimization",
"message": "Consider using batch operations for multiple messages"
}
],
"summary": {
"hasErrors": true,
"errorCount": 1,
"warningCount": 1,
"suggestionCount": 1
}
}
```
### How to Read It
#### 1. Check `valid` field
```javascript
if (result.valid) {
// ✅ Configuration is valid
} else {
// ❌ Has errors - must fix before deployment
}
```
#### 2. Fix errors first
```javascript
result.errors.forEach(error => {
console.log(`Error in ${error.property}: ${error.message}`);
console.log(`Fix: ${error.fix}`);
});
```
#### 3. Review warnings
```javascript
result.warnings.forEach(warning => {
console.log(`Warning: ${warning.message}`);
console.log(`Suggestion: ${warning.suggestion}`);
// Decide if you need to address this
});
```
#### 4. Consider suggestions
```javascript
// Optional improvements
// Not required but may enhance workflow
```
---
## Workflow Validation
### validate_workflow (Structure)
**Validates entire workflow**, not just individual nodes
**Checks**:
1. **Node configurations** - Each node valid
2. **Connections** - No broken references
3. **Expressions** - Syntax and references valid
4. **Flow** - Logical workflow structure
**Example**:
```javascript
validate_workflow({
workflow: {
nodes: [...],
connections: {...}
},
options: {
validateNodes: true,
validateConnections: true,
validateExpressions: true,
profile: "runtime"
}
})
```
### Common Workflow Errors
#### 1. Broken Connections
```json
{
"error": "Connection from 'Transform' to 'NonExistent' - target node not found"
}
```
**Fix**: Remove stale connection or create missing node
#### 2. Circular Dependencies
```json
{
"error": "Circular dependency detected: Node A → Node B → Node A"
}
```
**Fix**: Restructure workflow to remove loop
#### 3. Multiple Start Nodes
```json
{
"warning": "Multiple trigger nodes found - only one will execute"
}
```
**Fix**: Remove extra triggers or split into separate workflows
#### 4. Disconnected Nodes
```json
{
"warning": "Node 'Transform' is not connected to workflow flow"
}
```
**Fix**: Connect node or remove if unused
---
## Recovery Strategies
### Strategy 1: Start Fresh
**When**: Configuration is severely broken
**Steps**:
1. Note required fields from `get_node_essentials`
2. Create minimal valid configuration
3. Add features incrementally
4. Validate after each addition
### Strategy 2: Binary Search
**When**: Workflow validates but executes incorrectly
**Steps**:
1. Remove half the nodes
2. Validate and test
3. If works: problem is in removed nodes
4. If fails: problem is in remaining nodes
5. Repeat until problem isolated
### Strategy 3: Clean Stale Connections
**When**: "Node not found" errors
**Steps**:
```javascript
n8n_update_partial_workflow({
id: "workflow-id",
operations: [{
type: "cleanStaleConnections"
}]
})
```
### Strategy 4: Use Auto-fix
**When**: Operator structure errors
**Steps**:
```javascript
n8n_autofix_workflow({
id: "workflow-id",
applyFixes: false // Preview first
})
// Review fixes, then apply
n8n_autofix_workflow({
id: "workflow-id",
applyFixes: true
})
```
---
## Best Practices
### ✅ Do
- Validate after every significant change
- Read error messages completely
- Fix errors iteratively (one at a time)
- Use `runtime` profile for pre-deployment
- Check `valid` field before assuming success
- Trust auto-sanitization for operator issues
- Use `get_node_essentials` when unclear about requirements
- Document false positives you accept
### ❌ Don't
- Skip validation before activation
- Try to fix all errors at once
- Ignore error messages
- Use `strict` profile during development (too noisy)
- Assume validation passed (always check result)
- Manually fix auto-sanitization issues
- Deploy with unresolved errors
- Ignore all warnings (some are important!)
---
## Detailed Guides
For comprehensive error catalogs and false positive examples:
- **[ERROR_CATALOG.md](ERROR_CATALOG.md)** - Complete list of error types with examples
- **[FALSE_POSITIVES.md](FALSE_POSITIVES.md)** - When warnings are acceptable
---
## Summary
**Key Points**:
1. **Validation is iterative** (avg 2-3 cycles, 23s + 58s)
2. **Errors must be fixed**, warnings are optional
3. **Auto-sanitization** fixes operator structures automatically
4. **Use runtime profile** for balanced validation
5. **False positives exist** - learn to recognize them
6. **Read error messages** - they contain fix guidance
**Validation Process**:
1. Validate → Read errors → Fix → Validate again
2. Repeat until valid (usually 2-3 iterations)
3. Review warnings and decide if acceptable
4. Deploy with confidence
**Related Skills**:
- n8n MCP Tools Expert - Use validation tools correctly
- n8n Expression Syntax - Fix expression errors
- n8n Node Configuration - Understand required fields