[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M716MHSCPHSM03RVM8CMX65B":3,"skill-same:01M716MHSCPHSM03RVM8CMX65B":53},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":28,"linkOnly":29,"markdownContent":30,"markdownBody":31,"frontMatter":32,"refName":33,"commitSha":34,"skillDirectory":35,"forksCount":14,"repositoryHtmlUrl":36,"repositoryHomepageUrl":6,"ownerHtmlUrl":37,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":38,"install":39,"resources":52},"01M716MHSCPHSM03RVM8CMX65B","n8n-validation-expert",null,"Expert guide for interpreting and fixing n8n validation errors.","sapsapshen\u002Fai-memory-router","sapsapshen","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F20347959?v=4","01M6XDQEF1DP50DKF37H81J3J5","shenmian","01M6XDQEJPE41Y3DT2763X8ZJN",0,"MIT","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fcursor\u002Fn8n-validation-expert\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27],"validation","n8n validation expert","expert","n8n","guide","community","errors","for","unknown","2026-11-10 10:12:30",false,"---\nname: n8n-validation-expert\ndescription: \"Expert guide for interpreting and fixing n8n validation errors.\"\nrisk: unknown\nsource: community\n---\n\n# n8n Validation Expert\n\nExpert guide for interpreting and fixing n8n validation errors.\n\n---\n\n## Validation Philosophy\n\n**Validate early, validate often**\n\nValidation is typically iterative:\n- Expect validation feedback loops\n- Usually 2-3 validate → fix cycles\n- Average: 23s thinking about errors, 58s fixing them\n\n**Key insight**: Validation is an iterative process, not one-shot!\n\n---\n\n## Error Severity Levels\n\n### 1. Errors (Must Fix)\n**Blocks workflow execution** - Must be resolved before activation\n\n**Types**:\n- `missing_required` - Required field not provided\n- `invalid_value` - Value doesn't match allowed options\n- `type_mismatch` - Wrong data type (string instead of number)\n- `invalid_reference` - Referenced node doesn't exist\n- `invalid_expression` - Expression syntax error\n\n**Example**:\n```json\n{\n  \"type\": \"missing_required\",\n  \"property\": \"channel\",\n  \"message\": \"Channel name is required\",\n  \"fix\": \"Provide a channel name (lowercase, no spaces, 1-80 characters)\"\n}\n```\n\n### 2. Warnings (Should Fix)\n**Doesn't block execution** - Workflow can be activated but may have issues\n\n**Types**:\n- `best_practice` - Recommended but not required\n- `deprecated` - Using old API\u002Ffeature\n- `performance` - Potential performance issue\n\n**Example**:\n```json\n{\n  \"type\": \"best_practice\",\n  \"property\": \"errorHandling\",\n  \"message\": \"Slack API can have rate limits\",\n  \"suggestion\": \"Add onError: 'continueRegularOutput' with retryOnFail\"\n}\n```\n\n### 3. Suggestions (Optional)\n**Nice to have** - Improvements that could enhance workflow\n\n**Types**:\n- `optimization` - Could be more efficient\n- `alternative` - Better way to achieve same result\n\n---\n\n## The Validation Loop\n\n### Pattern from Telemetry\n**7,841 occurrences** of this pattern:\n\n```\n1. Configure node\n   ↓\n2. validate_node (23 seconds thinking about errors)\n   ↓\n3. Read error messages carefully\n   ↓\n4. Fix errors\n   ↓\n5. validate_node again (58 seconds fixing)\n   ↓\n6. Repeat until valid (usually 2-3 iterations)\n```\n\n### Example\n```javascript\n\u002F\u002F Iteration 1\nlet config = {\n  resource: \"channel\",\n  operation: \"create\"\n};\n\nconst result1 = validate_node({\n  nodeType: \"nodes-base.slack\",\n  config,\n  profile: \"runtime\"\n});\n\u002F\u002F → Error: Missing \"name\"\n\n\u002F\u002F ⏱️  23 seconds thinking...\n\n\u002F\u002F Iteration 2\nconfig.name = \"general\";\n\nconst result2 = validate_node({\n  nodeType: \"nodes-base.slack\",\n  config,\n  profile: \"runtime\"\n});\n\u002F\u002F → Error: Missing \"text\"\n\n\u002F\u002F ⏱️  58 seconds fixing...\n\n\u002F\u002F Iteration 3\nconfig.text = \"Hello!\";\n\nconst result3 = validate_node({\n  nodeType: \"nodes-base.slack\",\n  config,\n  profile: \"runtime\"\n});\n\u002F\u002F → Valid! ✅\n```\n\n**This is normal!** Don't be discouraged by multiple iterations.\n\n---\n\n## Validation Profiles\n\nChoose the right profile for your stage:\n\n### minimal\n**Use when**: Quick checks during editing\n\n**Validates**:\n- Only required fields\n- Basic structure\n\n**Pros**: Fastest, most permissive\n**Cons**: May miss issues\n\n### runtime (RECOMMENDED)\n**Use when**: Pre-deployment validation\n\n**Validates**:\n- Required fields\n- Value types\n- Allowed values\n- Basic dependencies\n\n**Pros**: Balanced, catches real errors\n**Cons**: Some edge cases missed\n\n**This is the recommended profile for most use cases**\n\n### ai-friendly\n**Use when**: AI-generated configurations\n\n**Validates**:\n- Same as runtime\n- Reduces false positives\n- More tolerant of minor issues\n\n**Pros**: Less noisy for AI workflows\n**Cons**: May allow some questionable configs\n\n### strict\n**Use when**: Production deployment, critical workflows\n\n**Validates**:\n- Everything\n- Best practices\n- Performance concerns\n- Security issues\n\n**Pros**: Maximum safety\n**Cons**: Many warnings, some false positives\n\n---\n\n## Common Error Types\n\n### 1. missing_required\n**What it means**: A required field is not provided\n\n**How to fix**:\n1. Use `get_node` to see required fields\n2. Add the missing field to your configuration\n3. Provide an appropriate value\n\n**Example**:\n```javascript\n\u002F\u002F Error\n{\n  \"type\": \"missing_required\",\n  \"property\": \"channel\",\n  \"message\": \"Channel name is required\"\n}\n\n\u002F\u002F Fix\nconfig.channel = \"#general\";\n```\n\n### 2. invalid_value\n**What it means**: Value doesn't match allowed options\n\n**How to fix**:\n1. Check error message for allowed values\n2. Use `get_node` to see options\n3. Update to a valid value\n\n**Example**:\n```javascript\n\u002F\u002F Error\n{\n  \"type\": \"invalid_value\",\n  \"property\": \"operation\",\n  \"message\": \"Operation must be one of: post, update, delete\",\n  \"current\": \"send\"\n}\n\n\u002F\u002F Fix\nconfig.operation = \"post\";  \u002F\u002F Use valid operation\n```\n\n### 3. type_mismatch\n**What it means**: Wrong data type for field\n\n**How to fix**:\n1. Check expected type in error message\n2. Convert value to correct type\n\n**Example**:\n```javascript\n\u002F\u002F Error\n{\n  \"type\": \"type_mismatch\",\n  \"property\": \"limit\",\n  \"message\": \"Expected number, got string\",\n  \"current\": \"100\"\n}\n\n\u002F\u002F Fix\nconfig.limit = 100;  \u002F\u002F Number, not string\n```\n\n### 4. invalid_expression\n**What it means**: Expression syntax error\n\n**How to fix**:\n1. Use n8n Expression Syntax skill\n2. Check for missing `{{}}` or typos\n3. Verify node\u002Ffield references\n\n**Example**:\n```javascript\n\u002F\u002F Error\n{\n  \"type\": \"invalid_expression\",\n  \"property\": \"text\",\n  \"message\": \"Invalid expression: $json.name\",\n  \"current\": \"$json.name\"\n}\n\n\u002F\u002F Fix\nconfig.text = \"={{$json.name}}\";  \u002F\u002F Add {{}}\n```\n\n### 5. invalid_reference\n**What it means**: Referenced node doesn't exist\n\n**How to fix**:\n1. Check node name spelling\n2. Verify node exists in workflow\n3. Update reference to correct name\n\n**Example**:\n```javascript\n\u002F\u002F Error\n{\n  \"type\": \"invalid_reference\",\n  \"property\": \"expression\",\n  \"message\": \"Node 'HTTP Requets' does not exist\",\n  \"current\": \"={{$node['HTTP Requets'].json.data}}\"\n}\n\n\u002F\u002F Fix - correct typo\nconfig.expression = \"={{$node['HTTP Request'].json.data}}\";\n```\n\n---\n\n## Auto-Sanitization System\n\n### What It Does\n**Automatically fixes common operator structure issues** on ANY workflow update\n\n**Runs when**:\n- `n8n_create_workflow`\n- `n8n_update_partial_workflow`\n- Any workflow save operation\n\n### What It Fixes\n\n#### 1. Binary Operators (Two Values)\n**Operators**: equals, notEquals, contains, notContains, greaterThan, lessThan, startsWith, endsWith\n\n**Fix**: Removes `singleValue` property (binary operators compare two values)\n\n**Before**:\n```javascript\n{\n  \"type\": \"boolean\",\n  \"operation\": \"equals\",\n  \"singleValue\": true  \u002F\u002F ❌ Wrong!\n}\n```\n\n**After** (automatic):\n```javascript\n{\n  \"type\": \"boolean\",\n  \"operation\": \"equals\"\n  \u002F\u002F singleValue removed ✅\n}\n```\n\n#### 2. Unary Operators (One Value)\n**Operators**: isEmpty, isNotEmpty, true, false\n\n**Fix**: Adds `singleValue: true` (unary operators check single value)\n\n**Before**:\n```javascript\n{\n  \"type\": \"boolean\",\n  \"operation\": \"isEmpty\"\n  \u002F\u002F Missing singleValue ❌\n}\n```\n\n**After** (automatic):\n```javascript\n{\n  \"type\": \"boolean\",\n  \"operation\": \"isEmpty\",\n  \"singleValue\": true  \u002F\u002F ✅ Added\n}\n```\n\n#### 3. IF\u002FSwitch Metadata\n**Fix**: Adds complete `conditions.options` metadata for IF v2.2+ and Switch v3.2+\n\n### What It CANNOT Fix\n\n#### 1. Broken Connections\nReferences to non-existent nodes\n\n**Solution**: Use `cleanStaleConnections` operation in `n8n_update_partial_workflow`\n\n#### 2. Branch Count Mismatches\n3 Switch rules but only 2 output connections\n\n**Solution**: Add missing connections or remove extra rules\n\n#### 3. Paradoxical Corrupt States\nAPI returns corrupt data but rejects updates\n\n**Solution**: May require manual database intervention\n\n---\n\n## False Positives\n\n### What Are They?\nValidation warnings that are technically \"wrong\" but acceptable in your use case\n\n### Common False Positives\n\n#### 1. \"Missing error handling\"\n**Warning**: No error handling configured\n\n**When acceptable**:\n- Simple workflows where failures are obvious\n- Testing\u002Fdevelopment workflows\n- Non-critical notifications\n\n**When to fix**: Production workflows handling important data\n\n#### 2. \"No retry logic\"\n**Warning**: Node doesn't retry on failure\n\n**When acceptable**:\n- APIs with their own retry logic\n- Idempotent operations\n- Manual trigger workflows\n\n**When to fix**: Flaky external services, production automation\n\n#### 3. \"Missing rate limiting\"\n**Warning**: No rate limiting for API calls\n\n**When acceptable**:\n- Internal APIs with no limits\n- Low-volume workflows\n- APIs with server-side rate limiting\n\n**When to fix**: Public APIs, high-volume workflows\n\n#### 4. \"Unbounded query\"\n**Warning**: SELECT without LIMIT\n\n**When acceptable**:\n- Small known datasets\n- Aggregation queries\n- Development\u002Ftesting\n\n**When to fix**: Production queries on large tables\n\n### Reducing False Positives\n\n**Use `ai-friendly` profile**:\n```javascript\nvalidate_node({\n  nodeType: \"nodes-base.slack\",\n  config: {...},\n  profile: \"ai-friendly\"  \u002F\u002F Fewer false positives\n})\n```\n\n---\n\n## Validation Result Structure\n\n### Complete Response\n```javascript\n{\n  \"valid\": false,\n  \"errors\": [\n    {\n      \"type\": \"missing_required\",\n      \"property\": \"channel\",\n      \"message\": \"Channel name is required\",\n      \"fix\": \"Provide a channel name (lowercase, no spaces)\"\n    }\n  ],\n  \"warnings\": [\n    {\n      \"type\": \"best_practice\",\n      \"property\": \"errorHandling\",\n      \"message\": \"Slack API can have rate limits\",\n      \"suggestion\": \"Add onError: 'continueRegularOutput'\"\n    }\n  ],\n  \"suggestions\": [\n    {\n      \"type\": \"optimization\",\n      \"message\": \"Consider using batch operations for multiple messages\"\n    }\n  ],\n  \"summary\": {\n    \"hasErrors\": true,\n    \"errorCount\": 1,\n    \"warningCount\": 1,\n    \"suggestionCount\": 1\n  }\n}\n```\n\n### How to Read It\n\n#### 1. Check `valid` field\n```javascript\nif (result.valid) {\n  \u002F\u002F ✅ Configuration is valid\n} else {\n  \u002F\u002F ❌ Has errors - must fix before deployment\n}\n```\n\n#### 2. Fix errors first\n```javascript\nresult.errors.forEach(error => {\n  console.log(`Error in ${error.property}: ${error.message}`);\n  console.log(`Fix: ${error.fix}`);\n});\n```\n\n#### 3. Review warnings\n```javascript\nresult.warnings.forEach(warning => {\n  console.log(`Warning: ${warning.message}`);\n  console.log(`Suggestion: ${warning.suggestion}`);\n  \u002F\u002F Decide if you need to address this\n});\n```\n\n#### 4. Consider suggestions\n```javascript\n\u002F\u002F Optional improvements\n\u002F\u002F Not required but may enhance workflow\n```\n\n---\n\n## Workflow Validation\n\n### validate_workflow (Structure)\n**Validates entire workflow**, not just individual nodes\n\n**Checks**:\n1. **Node configurations** - Each node valid\n2. **Connections** - No broken references\n3. **Expressions** - Syntax and references valid\n4. **Flow** - Logical workflow structure\n\n**Example**:\n```javascript\nvalidate_workflow({\n  workflow: {\n    nodes: [...],\n    connections: {...}\n  },\n  options: {\n    validateNodes: true,\n    validateConnections: true,\n    validateExpressions: true,\n    profile: \"runtime\"\n  }\n})\n```\n\n### Common Workflow Errors\n\n#### 1. Broken Connections\n```json\n{\n  \"error\": \"Connection from 'Transform' to 'NonExistent' - target node not found\"\n}\n```\n\n**Fix**: Remove stale connection or create missing node\n\n#### 2. Circular Dependencies\n```json\n{\n  \"error\": \"Circular dependency detected: Node A → Node B → Node A\"\n}\n```\n\n**Fix**: Restructure workflow to remove loop\n\n#### 3. Multiple Start Nodes\n```json\n{\n  \"warning\": \"Multiple trigger nodes found - only one will execute\"\n}\n```\n\n**Fix**: Remove extra triggers or split into separate workflows\n\n#### 4. Disconnected Nodes\n```json\n{\n  \"warning\": \"Node 'Transform' is not connected to workflow flow\"\n}\n```\n\n**Fix**: Connect node or remove if unused\n\n---\n\n## Recovery Strategies\n\n### Strategy 1: Start Fresh\n**When**: Configuration is severely broken\n\n**Steps**:\n1. Note required fields from `get_node`\n2. Create minimal valid configuration\n3. Add features incrementally\n4. Validate after each addition\n\n### Strategy 2: Binary Search\n**When**: Workflow validates but executes incorrectly\n\n**Steps**:\n1. Remove half the nodes\n2. Validate and test\n3. If works: problem is in removed nodes\n4. If fails: problem is in remaining nodes\n5. Repeat until problem isolated\n\n### Strategy 3: Clean Stale Connections\n**When**: \"Node not found\" errors\n\n**Steps**:\n```javascript\nn8n_update_partial_workflow({\n  id: \"workflow-id\",\n  operations: [{\n    type: \"cleanStaleConnections\"\n  }]\n})\n```\n\n### Strategy 4: Use Auto-fix\n**When**: Operator structure errors\n\n**Steps**:\n```javascript\nn8n_autofix_workflow({\n  id: \"workflow-id\",\n  applyFixes: false  \u002F\u002F Preview first\n})\n\n\u002F\u002F Review fixes, then apply\nn8n_autofix_workflow({\n  id: \"workflow-id\",\n  applyFixes: true\n})\n```\n\n---\n\n## Best Practices\n\n### ✅ Do\n\n- Validate after every significant change\n- Read error messages completely\n- Fix errors iteratively (one at a time)\n- Use `runtime` profile for pre-deployment\n- Check `valid` field before assuming success\n- Trust auto-sanitization for operator issues\n- Use `get_node` when unclear about requirements\n- Document false positives you accept\n\n### ❌ Don't\n\n- Skip validation before activation\n- Try to fix all errors at once\n- Ignore error messages\n- Use `strict` profile during development (too noisy)\n- Assume validation passed (always check result)\n- Manually fix auto-sanitization issues\n- Deploy with unresolved errors\n- Ignore all warnings (some are important!)\n\n---\n\n## Detailed Guides\n\nFor comprehensive error catalogs and false positive examples:\n\n- **ERROR_CATALOG.md** - Complete list of error types with examples\n- **FALSE_POSITIVES.md** - When warnings are acceptable\n\n---\n\n## Summary\n\n**Key Points**:\n1. **Validation is iterative** (avg 2-3 cycles, 23s + 58s)\n2. **Errors must be fixed**, warnings are optional\n3. **Auto-sanitization** fixes operator structures automatically\n4. **Use runtime profile** for balanced validation\n5. **False positives exist** - learn to recognize them\n6. **Read error messages** - they contain fix guidance\n\n**Validation Process**:\n1. Validate → Read errors → Fix → Validate again\n2. Repeat until valid (usually 2-3 iterations)\n3. Review warnings and decide if acceptable\n4. Deploy with confidence\n\n**Related Skills**:\n- n8n MCP Tools Expert - Use validation tools correctly\n- n8n Expression Syntax - Fix expression errors\n- n8n Node Configuration - Understand required fields\n","# n8n Validation Expert\n\nExpert guide for interpreting and fixing n8n validation errors.\n\n---\n\n## Validation Philosophy\n\n**Validate early, validate often**\n\nValidation is typically iterative:\n- Expect validation feedback loops\n- Usually 2-3 validate → fix cycles\n- Average: 23s thinking about errors, 58s fixing them\n\n**Key insight**: Validation is an iterative process, not one-shot!\n\n---\n\n## Error Severity Levels\n\n### 1. Errors (Must Fix)\n**Blocks workflow execution** - Must be resolved before activation\n\n**Types**:\n- `missing_required` - Required field not provided\n- `invalid_value` - Value doesn't match allowed options\n- `type_mismatch` - Wrong data type (string instead of number)\n- `invalid_reference` - Referenced node doesn't exist\n- `invalid_expression` - Expression syntax error\n\n**Example**:\n```json\n{\n  \"type\": \"missing_required\",\n  \"property\": \"channel\",\n  \"message\": \"Channel name is required\",\n  \"fix\": \"Provide a channel name (lowercase, no spaces, 1-80 characters)\"\n}\n```\n\n### 2. Warnings (Should Fix)\n**Doesn't block execution** - Workflow can be activated but may have issues\n\n**Types**:\n- `best_practice` - Recommended but not required\n- `deprecated` - Using old API\u002Ffeature\n- `performance` - Potential performance issue\n\n**Example**:\n```json\n{\n  \"type\": \"best_practice\",\n  \"property\": \"errorHandling\",\n  \"message\": \"Slack API can have rate limits\",\n  \"suggestion\": \"Add onError: 'continueRegularOutput' with retryOnFail\"\n}\n```\n\n### 3. Suggestions (Optional)\n**Nice to have** - Improvements that could enhance workflow\n\n**Types**:\n- `optimization` - Could be more efficient\n- `alternative` - Better way to achieve same result\n\n---\n\n## The Validation Loop\n\n### Pattern from Telemetry\n**7,841 occurrences** of this pattern:\n\n```\n1. Configure node\n   ↓\n2. validate_node (23 seconds thinking about errors)\n   ↓\n3. Read error messages carefully\n   ↓\n4. Fix errors\n   ↓\n5. validate_node again (58 seconds fixing)\n   ↓\n6. Repeat until valid (usually 2-3 iterations)\n```\n\n### Example\n```javascript\n\u002F\u002F Iteration 1\nlet config = {\n  resource: \"channel\",\n  operation: \"create\"\n};\n\nconst result1 = validate_node({\n  nodeType: \"nodes-base.slack\",\n  config,\n  profile: \"runtime\"\n});\n\u002F\u002F → Error: Missing \"name\"\n\n\u002F\u002F ⏱️  23 seconds thinking...\n\n\u002F\u002F Iteration 2\nconfig.name = \"general\";\n\nconst result2 = validate_node({\n  nodeType: \"nodes-base.slack\",\n  config,\n  profile: \"runtime\"\n});\n\u002F\u002F → Error: Missing \"text\"\n\n\u002F\u002F ⏱️  58 seconds fixing...\n\n\u002F\u002F Iteration 3\nconfig.text = \"Hello!\";\n\nconst result3 = validate_node({\n  nodeType: \"nodes-base.slack\",\n  config,\n  profile: \"runtime\"\n});\n\u002F\u002F → Valid! ✅\n```\n\n**This is normal!** Don't be discouraged by multiple iterations.\n\n---\n\n## Validation Profiles\n\nChoose the right profile for your stage:\n\n### minimal\n**Use when**: Quick checks during editing\n\n**Validates**:\n- Only required fields\n- Basic structure\n\n**Pros**: Fastest, most permissive\n**Cons**: May miss issues\n\n### runtime (RECOMMENDED)\n**Use when**: Pre-deployment validation\n\n**Validates**:\n- Required fields\n- Value types\n- Allowed values\n- Basic dependencies\n\n**Pros**: Balanced, catches real errors\n**Cons**: Some edge cases missed\n\n**This is the recommended profile for most use cases**\n\n### ai-friendly\n**Use when**: AI-generated configurations\n\n**Validates**:\n- Same as runtime\n- Reduces false positives\n- More tolerant of minor issues\n\n**Pros**: Less noisy for AI workflows\n**Cons**: May allow some questionable configs\n\n### strict\n**Use when**: Production deployment, critical workflows\n\n**Validates**:\n- Everything\n- Best practices\n- Performance concerns\n- Security issues\n\n**Pros**: Maximum safety\n**Cons**: Many warnings, some false positives\n\n---\n\n## Common Error Types\n\n### 1. missing_required\n**What it means**: A required field is not provided\n\n**How to fix**:\n1. Use `get_node` to see required fields\n2. Add the missing field to your configuration\n3. Provide an appropriate value\n\n**Example**:\n```javascript\n\u002F\u002F Error\n{\n  \"type\": \"missing_required\",\n  \"property\": \"channel\",\n  \"message\": \"Channel name is required\"\n}\n\n\u002F\u002F Fix\nconfig.channel = \"#general\";\n```\n\n### 2. invalid_value\n**What it means**: Value doesn't match allowed options\n\n**How to fix**:\n1. Check error message for allowed values\n2. Use `get_node` to see options\n3. Update to a valid value\n\n**Example**:\n```javascript\n\u002F\u002F Error\n{\n  \"type\": \"invalid_value\",\n  \"property\": \"operation\",\n  \"message\": \"Operation must be one of: post, update, delete\",\n  \"current\": \"send\"\n}\n\n\u002F\u002F Fix\nconfig.operation = \"post\";  \u002F\u002F Use valid operation\n```\n\n### 3. type_mismatch\n**What it means**: Wrong data type for field\n\n**How to fix**:\n1. Check expected type in error message\n2. Convert value to correct type\n\n**Example**:\n```javascript\n\u002F\u002F Error\n{\n  \"type\": \"type_mismatch\",\n  \"property\": \"limit\",\n  \"message\": \"Expected number, got string\",\n  \"current\": \"100\"\n}\n\n\u002F\u002F Fix\nconfig.limit = 100;  \u002F\u002F Number, not string\n```\n\n### 4. invalid_expression\n**What it means**: Expression syntax error\n\n**How to fix**:\n1. Use n8n Expression Syntax skill\n2. Check for missing `{{}}` or typos\n3. Verify node\u002Ffield references\n\n**Example**:\n```javascript\n\u002F\u002F Error\n{\n  \"type\": \"invalid_expression\",\n  \"property\": \"text\",\n  \"message\": \"Invalid expression: $json.name\",\n  \"current\": \"$json.name\"\n}\n\n\u002F\u002F Fix\nconfig.text = \"={{$json.name}}\";  \u002F\u002F Add {{}}\n```\n\n### 5. invalid_reference\n**What it means**: Referenced node doesn't exist\n\n**How to fix**:\n1. Check node name spelling\n2. Verify node exists in workflow\n3. Update reference to correct name\n\n**Example**:\n```javascript\n\u002F\u002F Error\n{\n  \"type\": \"invalid_reference\",\n  \"property\": \"expression\",\n  \"message\": \"Node 'HTTP Requets' does not exist\",\n  \"current\": \"={{$node['HTTP Requets'].json.data}}\"\n}\n\n\u002F\u002F Fix - correct typo\nconfig.expression = \"={{$node['HTTP Request'].json.data}}\";\n```\n\n---\n\n## Auto-Sanitization System\n\n### What It Does\n**Automatically fixes common operator structure issues** on ANY workflow update\n\n**Runs when**:\n- `n8n_create_workflow`\n- `n8n_update_partial_workflow`\n- Any workflow save operation\n\n### What It Fixes\n\n#### 1. Binary Operators (Two Values)\n**Operators**: equals, notEquals, contains, notContains, greaterThan, lessThan, startsWith, endsWith\n\n**Fix**: Removes `singleValue` property (binary operators compare two values)\n\n**Before**:\n```javascript\n{\n  \"type\": \"boolean\",\n  \"operation\": \"equals\",\n  \"singleValue\": true  \u002F\u002F ❌ Wrong!\n}\n```\n\n**After** (automatic):\n```javascript\n{\n  \"type\": \"boolean\",\n  \"operation\": \"equals\"\n  \u002F\u002F singleValue removed ✅\n}\n```\n\n#### 2. Unary Operators (One Value)\n**Operators**: isEmpty, isNotEmpty, true, false\n\n**Fix**: Adds `singleValue: true` (unary operators check single value)\n\n**Before**:\n```javascript\n{\n  \"type\": \"boolean\",\n  \"operation\": \"isEmpty\"\n  \u002F\u002F Missing singleValue ❌\n}\n```\n\n**After** (automatic):\n```javascript\n{\n  \"type\": \"boolean\",\n  \"operation\": \"isEmpty\",\n  \"singleValue\": true  \u002F\u002F ✅ Added\n}\n```\n\n#### 3. IF\u002FSwitch Metadata\n**Fix**: Adds complete `conditions.options` metadata for IF v2.2+ and Switch v3.2+\n\n### What It CANNOT Fix\n\n#### 1. Broken Connections\nReferences to non-existent nodes\n\n**Solution**: Use `cleanStaleConnections` operation in `n8n_update_partial_workflow`\n\n#### 2. Branch Count Mismatches\n3 Switch rules but only 2 output connections\n\n**Solution**: Add missing connections or remove extra rules\n\n#### 3. Paradoxical Corrupt States\nAPI returns corrupt data but rejects updates\n\n**Solution**: May require manual database intervention\n\n---\n\n## False Positives\n\n### What Are They?\nValidation warnings that are technically \"wrong\" but acceptable in your use case\n\n### Common False Positives\n\n#### 1. \"Missing error handling\"\n**Warning**: No error handling configured\n\n**When acceptable**:\n- Simple workflows where failures are obvious\n- Testing\u002Fdevelopment workflows\n- Non-critical notifications\n\n**When to fix**: Production workflows handling important data\n\n#### 2. \"No retry logic\"\n**Warning**: Node doesn't retry on failure\n\n**When acceptable**:\n- APIs with their own retry logic\n- Idempotent operations\n- Manual trigger workflows\n\n**When to fix**: Flaky external services, production automation\n\n#### 3. \"Missing rate limiting\"\n**Warning**: No rate limiting for API calls\n\n**When acceptable**:\n- Internal APIs with no limits\n- Low-volume workflows\n- APIs with server-side rate limiting\n\n**When to fix**: Public APIs, high-volume workflows\n\n#### 4. \"Unbounded query\"\n**Warning**: SELECT without LIMIT\n\n**When acceptable**:\n- Small known datasets\n- Aggregation queries\n- Development\u002Ftesting\n\n**When to fix**: Production queries on large tables\n\n### Reducing False Positives\n\n**Use `ai-friendly` profile**:\n```javascript\nvalidate_node({\n  nodeType: \"nodes-base.slack\",\n  config: {...},\n  profile: \"ai-friendly\"  \u002F\u002F Fewer false positives\n})\n```\n\n---\n\n## Validation Result Structure\n\n### Complete Response\n```javascript\n{\n  \"valid\": false,\n  \"errors\": [\n    {\n      \"type\": \"missing_required\",\n      \"property\": \"channel\",\n      \"message\": \"Channel name is required\",\n      \"fix\": \"Provide a channel name (lowercase, no spaces)\"\n    }\n  ],\n  \"warnings\": [\n    {\n      \"type\": \"best_practice\",\n      \"property\": \"errorHandling\",\n      \"message\": \"Slack API can have rate limits\",\n      \"suggestion\": \"Add onError: 'continueRegularOutput'\"\n    }\n  ],\n  \"suggestions\": [\n    {\n      \"type\": \"optimization\",\n      \"message\": \"Consider using batch operations for multiple messages\"\n    }\n  ],\n  \"summary\": {\n    \"hasErrors\": true,\n    \"errorCount\": 1,\n    \"warningCount\": 1,\n    \"suggestionCount\": 1\n  }\n}\n```\n\n### How to Read It\n\n#### 1. Check `valid` field\n```javascript\nif (result.valid) {\n  \u002F\u002F ✅ Configuration is valid\n} else {\n  \u002F\u002F ❌ Has errors - must fix before deployment\n}\n```\n\n#### 2. Fix errors first\n```javascript\nresult.errors.forEach(error => {\n  console.log(`Error in ${error.property}: ${error.message}`);\n  console.log(`Fix: ${error.fix}`);\n});\n```\n\n#### 3. Review warnings\n```javascript\nresult.warnings.forEach(warning => {\n  console.log(`Warning: ${warning.message}`);\n  console.log(`Suggestion: ${warning.suggestion}`);\n  \u002F\u002F Decide if you need to address this\n});\n```\n\n#### 4. Consider suggestions\n```javascript\n\u002F\u002F Optional improvements\n\u002F\u002F Not required but may enhance workflow\n```\n\n---\n\n## Workflow Validation\n\n### validate_workflow (Structure)\n**Validates entire workflow**, not just individual nodes\n\n**Checks**:\n1. **Node configurations** - Each node valid\n2. **Connections** - No broken references\n3. **Expressions** - Syntax and references valid\n4. **Flow** - Logical workflow structure\n\n**Example**:\n```javascript\nvalidate_workflow({\n  workflow: {\n    nodes: [...],\n    connections: {...}\n  },\n  options: {\n    validateNodes: true,\n    validateConnections: true,\n    validateExpressions: true,\n    profile: \"runtime\"\n  }\n})\n```\n\n### Common Workflow Errors\n\n#### 1. Broken Connections\n```json\n{\n  \"error\": \"Connection from 'Transform' to 'NonExistent' - target node not found\"\n}\n```\n\n**Fix**: Remove stale connection or create missing node\n\n#### 2. Circular Dependencies\n```json\n{\n  \"error\": \"Circular dependency detected: Node A → Node B → Node A\"\n}\n```\n\n**Fix**: Restructure workflow to remove loop\n\n#### 3. Multiple Start Nodes\n```json\n{\n  \"warning\": \"Multiple trigger nodes found - only one will execute\"\n}\n```\n\n**Fix**: Remove extra triggers or split into separate workflows\n\n#### 4. Disconnected Nodes\n```json\n{\n  \"warning\": \"Node 'Transform' is not connected to workflow flow\"\n}\n```\n\n**Fix**: Connect node or remove if unused\n\n---\n\n## Recovery Strategies\n\n### Strategy 1: Start Fresh\n**When**: Configuration is severely broken\n\n**Steps**:\n1. Note required fields from `get_node`\n2. Create minimal valid configuration\n3. Add features incrementally\n4. Validate after each addition\n\n### Strategy 2: Binary Search\n**When**: Workflow validates but executes incorrectly\n\n**Steps**:\n1. Remove half the nodes\n2. Validate and test\n3. If works: problem is in removed nodes\n4. If fails: problem is in remaining nodes\n5. Repeat until problem isolated\n\n### Strategy 3: Clean Stale Connections\n**When**: \"Node not found\" errors\n\n**Steps**:\n```javascript\nn8n_update_partial_workflow({\n  id: \"workflow-id\",\n  operations: [{\n    type: \"cleanStaleConnections\"\n  }]\n})\n```\n\n### Strategy 4: Use Auto-fix\n**When**: Operator structure errors\n\n**Steps**:\n```javascript\nn8n_autofix_workflow({\n  id: \"workflow-id\",\n  applyFixes: false  \u002F\u002F Preview first\n})\n\n\u002F\u002F Review fixes, then apply\nn8n_autofix_workflow({\n  id: \"workflow-id\",\n  applyFixes: true\n})\n```\n\n---\n\n## Best Practices\n\n### ✅ Do\n\n- Validate after every significant change\n- Read error messages completely\n- Fix errors iteratively (one at a time)\n- Use `runtime` profile for pre-deployment\n- Check `valid` field before assuming success\n- Trust auto-sanitization for operator issues\n- Use `get_node` when unclear about requirements\n- Document false positives you accept\n\n### ❌ Don't\n\n- Skip validation before activation\n- Try to fix all errors at once\n- Ignore error messages\n- Use `strict` profile during development (too noisy)\n- Assume validation passed (always check result)\n- Manually fix auto-sanitization issues\n- Deploy with unresolved errors\n- Ignore all warnings (some are important!)\n\n---\n\n## Detailed Guides\n\nFor comprehensive error catalogs and false positive examples:\n\n- **ERROR_CATALOG.md** - Complete list of error types with examples\n- **FALSE_POSITIVES.md** - When warnings are acceptable\n\n---\n\n## Summary\n\n**Key Points**:\n1. **Validation is iterative** (avg 2-3 cycles, 23s + 58s)\n2. **Errors must be fixed**, warnings are optional\n3. **Auto-sanitization** fixes operator structures automatically\n4. **Use runtime profile** for balanced validation\n5. **False positives exist** - learn to recognize them\n6. **Read error messages** - they contain fix guidance\n\n**Validation Process**:\n1. Validate → Read errors → Fix → Validate again\n2. Repeat until valid (usually 2-3 iterations)\n3. Review warnings and decide if acceptable\n4. Deploy with confidence\n\n**Related Skills**:\n- n8n MCP Tools Expert - Use validation tools correctly\n- n8n Expression Syntax - Fix expression errors\n- n8n Node Configuration - Understand required fields\n",{"name":5,"risk":27,"source":24,"description":7},"main","7a38d8e7073e61c16eda85681cb32fb68a8657a5","skills-store\u002Fcursor\u002Fn8n-validation-expert","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router","https:\u002F\u002Fgithub.com\u002Fsapsapshen","2026-04-14 21:12:12",{"source":8,"skillName":5,"commands":40,"prompt":50,"zipAvailable":51},[41,44,47],{"tool":42,"command":43},"npx","npx skills add sapsapshen\u002Fai-memory-router --skill n8n-validation-expert",{"tool":45,"command":46},"bunx","bunx skills add sapsapshen\u002Fai-memory-router --skill n8n-validation-expert",{"tool":48,"command":49},"pnpm","pnpm dlx skills add sapsapshen\u002Fai-memory-router --skill n8n-validation-expert","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fcursor\u002Fn8n-validation-expert\u002FSKILL.md",true,[],[54,78,104,114,127,146],{"skillNo":55,"name":56,"nameZh":6,"description":57,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":58,"categories":59,"keywords":65,"publishedAt":28},"01M71ATQRKG48SH06FQ697T5G9","wechat-search","Search WeChat Official Account articles using OpenClaw's web search and fetch capabilities with compliance-focused design.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fwechat-search-release\u002FSKILL.md",[60],{"categoryNo":61,"categoryName":62,"taxonomyType":63,"taxonomyTypeDesc":64},"01JBSEEDCAT000000000000037","律师与法务","PROFESSION","适用职业",[66,67,68,69,70,71,72,73,74,75,76,77],"wechat search","wechat","search","capabilities","openclaw","design","web search","compliance","web","official","fetch","with",{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":28},"01M71ATNAVGZB35PFYM2GC5N00","trend-tap","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend tap', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-tap\u002FSKILL.md",[],[85,86,87,88,89,90,68,91,92,93,94,95,96,97,98,99,100,101,102,103],"trend","trend tap","tap","api keys","Bash","time","trending","hacker","aggregator","do","when","brew","live","data","google","install","read","across","api",{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":110,"publishedAt":28},"01M71ATJ9AM5KM15AA8PS302EB","trend-radar","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend pulse', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-radar\u002FSKILL.md",[],[111,112,85,96,97,98,99,89,68,101,113,102,103,95,93,92,91,100,90,88],"trend radar","radar","pulse",{"skillNo":115,"name":116,"nameZh":6,"description":117,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":118,"categories":119,"keywords":120,"publishedAt":28},"01M71ATGF095N3EJM9G8SD0BB5","tech-news-daily","每日科技新闻汇——从全球多个 RSS 源抓取最新科技新闻，翻译（英→中）、去重、排版成每日简报。当用户询问科技新闻、科技新鲜事、每日科技、技术动态、Daily Tech News 或类似表达时触发此技能。","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftech-news-daily\u002FSKILL.md",[],[121,122,123,124,125,126],"news","tech","tech news daily","daily","rss","翻译",{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":138,"publishedAt":28},"01M71ATFAEAMQ17M70NQNY7SR8","summarize","Summarize URLs or files with the summarize CLI (web, PDFs, images, audio, YouTube).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsummarize\u002FSKILL.md",[133],{"categoryNo":134,"categoryName":135,"taxonomyType":136,"taxonomyTypeDesc":137},"01JBSEEDCAT000000000000021","资料检索与研究","SCENARIO","使用场景",[129,74,139,140,141,77,96,142,143,144,87,145,100],"Audio","cli","youtube","images","https","files","pdfs",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":150,"categories":151,"keywords":152,"publishedAt":28},"01M71ATDNS3R0M4H936PACQAWZ","sonoscli","Control Sonos speakers (discover\u002Fstatus\u002Fplay\u002Fvolume\u002Fgroup).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsonoscli\u002FSKILL.md",[],[148,153,154,155,100,156,143,157,158,159,160,161],"status","play","go","latest","github","discover","control","cmd","volume"]