AgentSkillsCN

08 Validation Expert

08 验证专家

SKILL.md

n8n Validation Expert

Complete guide to interpreting errors, validating workflows, and ensuring production readiness

Overview

This skill covers workflow validation, error interpretation, and production readiness. It includes a complete error catalog, validation profiles (minimal, runtime, ai-friendly, strict), auto-fix tools, error handling patterns, and pre-deployment checklists. Use this when encountering validation errors or preparing workflows for production.


Quick Reference

NeedTool/Action
Validate single nodevalidate_node() with profile
Validate full workflown8n_validate_workflow()
Auto-fix common issuesn8n_autofix_workflow()
Clean broken connectionscleanStaleConnections operation
Error handling setupError Trigger workflow

Part 1: Validation Philosophy

The Iterative Process

Validation is NOT one-shot - expect multiple cycles:

code
Configure → Validate → Read Errors → Fix → Validate Again
        ↑                                    ↓
        └────────── Repeat (2-3 times) ──────┘

Telemetry Insights:

  • Average: 23 seconds thinking about errors
  • Average: 58 seconds fixing them
  • Typical: 2-3 validation cycles per node

Validate Early, Validate Often

  1. During Development: Use minimal profile for quick checks
  2. Before Testing: Use runtime profile
  3. Before Deployment: Use strict profile
  4. After Template Deploy: Always validate imported workflows

Part 2: Error Severity Levels

Level 1: Errors (Must Fix)

Blocks workflow execution - Cannot activate workflow until resolved

Error TypeDescriptionExample
missing_requiredRequired field not providedMissing channel name
invalid_valueValue not in allowed optionsWrong operation type
type_mismatchWrong data typeString instead of number
invalid_referenceReferenced node doesn't existTypo in node name
invalid_expressionExpression syntax errorMissing {{ }} wrapper
invalid_connectionConnection to non-existent nodeDeleted node still referenced

Level 2: Warnings (Should Fix)

Doesn't block execution - Workflow can activate but may have issues

Warning TypeDescription
best_practiceRecommended but not required
deprecatedUsing old API/feature
performancePotential performance issue
securityPotential security concern
missing_error_handlingNo error workflow configured

Level 3: Suggestions (Optional)

Nice to have - Improvements that could enhance workflow

  • Optimization opportunities
  • Alternative approaches
  • Documentation recommendations

Part 3: Complete Error Catalog

Authentication Errors

401 - Unauthorized

json
{
  "status": 401,
  "message": "Request failed with status code 401"
}

Causes:

  • Invalid or expired API key
  • Wrong credentials
  • Missing authentication header
  • OAuth token expired

Fixes:

  1. Verify API key in credentials
  2. Check if key was regenerated
  3. Refresh OAuth connection
  4. Verify account has required permissions

403 - Forbidden

json
{
  "status": 403,
  "message": "Forbidden - perhaps check your credentials"
}

Causes:

  • Valid credentials but insufficient permissions
  • IP not whitelisted
  • Account suspended
  • Resource access denied

Fixes:

  1. Check API permissions/scopes
  2. Verify IP whitelist settings
  3. Review account status
  4. Confirm resource access rights

Request Errors

400 - Bad Request

json
{
  "status": 400,
  "message": "Bad request - please check your parameters"
}

Causes:

  • Invalid parameter name or value
  • Malformed JSON body
  • Missing required parameters
  • Array not formatted correctly

Fixes:

  1. Review API documentation
  2. Validate JSON structure
  3. Check parameter names/values
  4. Use Array Format option for Query Parameters

404 - Not Found

json
{
  "status": 404,
  "message": "The resource you are requesting could not be found"
}

Causes:

  • Wrong endpoint URL
  • Resource deleted
  • ID doesn't exist
  • API version mismatch

Fixes:

  1. Verify endpoint URL
  2. Check if resource exists
  3. Confirm ID is correct
  4. Review API version

429 - Rate Limited

json
{
  "status": 429,
  "message": "The service is receiving too many requests from you"
}

Causes:

  • Too many requests in time window
  • Account rate limit exceeded
  • Concurrent request limit hit

Fixes:

  1. Enable "Retry On Fail" with delays
  2. Implement batching
  3. Add delays between items
  4. Upgrade API plan if needed

Configuration Errors

Missing Required Field

json
{
  "type": "missing_required",
  "property": "channel",
  "message": "Channel name is required",
  "fix": "Provide a channel name"
}

Fix Pattern:

javascript
// 1. Use get_node to see required fields
// 2. Add the missing field
config.channel = "#general";
// 3. Re-validate

Invalid Value

json
{
  "type": "invalid_value",
  "property": "operation",
  "message": "Operation must be one of: post, update, delete",
  "current": "send"
}

Fix Pattern:

javascript
// Check allowed values in error message or get_node
config.operation = "post";  // Use valid value

Type Mismatch

json
{
  "type": "type_mismatch",
  "property": "limit",
  "message": "Expected number, got string",
  "current": "100"
}

Fix Pattern:

javascript
config.limit = 100;  // Number, not "100" string

Expression Errors

Invalid Expression Syntax

json
{
  "type": "invalid_expression",
  "property": "text",
  "message": "Invalid expression: $json.name",
  "current": "$json.name"
}

Fix: Add ={{ }} wrapper:

javascript
config.text = "={{ $json.name }}";

Invalid Reference

json
{
  "type": "invalid_reference",
  "message": "Node 'HTTP Requets' does not exist"
}

Fix: Correct typo in node name:

javascript
// Wrong: $node['HTTP Requets']
// Correct: $node['HTTP Request']

Cannot Read Properties of Undefined

json
{
  "message": "Cannot read properties of undefined (reading 'name')"
}

Causes:

  • Accessing property on undefined object
  • Previous node didn't run
  • Expression references non-existent field
  • Optional chaining not used

Fixes:

javascript
// Use optional chaining
{{ $json.user?.profile?.name }}

// Provide default
{{ $json.name ?? 'default' }}

// Check node executed
{{ $("Previous Node").first()?.json?.field }}

Connection Errors

Database Connection Failed

json
{
  "message": "Cannot connect to database"
}

Causes:

  • Wrong connection string
  • Database server down
  • Network/firewall issue
  • Credentials incorrect

Fixes:

  1. Verify connection string
  2. Check database server status
  3. Test with database client (pgAdmin, etc.)
  4. Verify network access

Webhook Not Reachable

json
{
  "message": "Webhook URL not accessible"
}

Causes:

  • n8n not publicly accessible
  • Wrong webhook URL configured
  • Firewall blocking requests
  • SSL certificate issues

Fixes:

  1. Use tunneling (ngrok) for local development
  2. Verify public URL configuration
  3. Check firewall rules
  4. Verify SSL certificate

Part 4: Validation Profiles

ProfileWhen to UseWhat It Validates
minimalQuick checks during editingRequired fields, basic structure
runtimePre-deployment (RECOMMENDED)Required fields, types, allowed values
ai-friendlyAI-generated configsSame as runtime, fewer false positives
strictProduction, critical workflowsEverything + best practices + security

Usage

javascript
// Single node validation
validate_node({
  nodeType: "nodes-base.slack",
  config: { resource: "message", operation: "post" },
  mode: "full",
  profile: "runtime"  // RECOMMENDED
})

// Full workflow validation
n8n_validate_workflow({
  id: "workflow-id",
  options: {
    validateNodes: true,
    validateConnections: true,
    validateExpressions: true,
    profile: "runtime"
  }
})

Profile Selection Guide

code
Development → minimal (fast feedback)
     ↓
Testing → runtime (balanced)
     ↓
Production → strict (comprehensive)

AI-generated workflows → ai-friendly (reduces false positives)

Part 5: MCP Validation Tools

validate_node - Single Node Validation

javascript
validate_node({
  nodeType: "nodes-base.slack",
  config: {
    resource: "message",
    operation: "post",
    channel: "#general",
    text: "Hello!"
  },
  mode: "full",        // full or minimal
  profile: "runtime"   // minimal, runtime, ai-friendly, strict
})

n8n_validate_workflow - Workflow Validation

javascript
n8n_validate_workflow({
  id: "workflow-id",
  options: {
    validateNodes: true,       // Validate node configurations
    validateConnections: true, // Check connection integrity
    validateExpressions: true, // Validate expression syntax
    profile: "runtime"
  }
})

n8n_autofix_workflow - Auto-fix Issues

javascript
// Preview fixes first (ALWAYS do this)
n8n_autofix_workflow({
  id: "workflow-id",
  applyFixes: false,  // Preview mode
  confidenceThreshold: "medium"
})

// Then apply if fixes look correct
n8n_autofix_workflow({
  id: "workflow-id",
  applyFixes: true
})

Available Fix Types

Fix TypeWhat It Fixes
expression-formatMissing = prefix in expressions
typeversion-correctionIncorrect node typeVersion
typeversion-upgradeUpgrade to latest typeVersion
error-output-configError output configuration
node-type-correctionNode type mismatches
webhook-missing-pathMissing webhook paths
version-migrationv2.0+ migration issues

Targeted Fix Application

javascript
// Only apply specific fix types
n8n_autofix_workflow({
  id: "workflow-id",
  applyFixes: true,
  fixTypes: ["expression-format", "typeversion-upgrade"],
  confidenceThreshold: "high"  // Only high-confidence fixes
})

Part 6: Auto-Sanitization System

What It Does

Automatically fixes operator structure issues on ANY workflow update.

Runs when:

  • n8n_create_workflow
  • n8n_update_partial_workflow
  • Any workflow save operation

Binary Operators (Two Values)

Operators: equals, notEquals, contains, notContains, greaterThan, lessThan, startsWith, endsWith

Fix: Removes erroneous singleValue property

javascript
// Before (wrong)
{
  "operation": "equals",
  "singleValue": true  // ❌ Wrong for binary operator
}

// After (auto-fixed)
{
  "operation": "equals"
  // singleValue removed ✅
}

Unary Operators (One Value)

Operators: isEmpty, isNotEmpty, true, false

Fix: Adds required singleValue: true

javascript
// Before (missing)
{
  "operation": "isEmpty"
  // Missing singleValue ❌
}

// After (auto-fixed)
{
  "operation": "isEmpty",
  "singleValue": true  // ✅ Added
}

What Auto-Sanitization CANNOT Fix

IssueSolution
Broken connectionsUse cleanStaleConnections operation
Branch count mismatchesAdd missing connections manually
Paradoxical corrupt statesMay require database intervention
Expression logic errorsManual review required
Wrong node type entirelyReplace node manually

Part 7: Common Node-Specific Errors

HTTP Request Node

ErrorCauseFix
"JSON parameter need to be valid JSON"Malformed JSON bodyValidate JSON structure
"Bad request - check parameters"Invalid query paramsReview API docs, check array format
401/403 errorsAuth issuesVerify credentials and permissions
SSL certificate errorsSelf-signed certEnable "Ignore SSL Issues" option

Code Node

ErrorCauseFix
"Code doesn't return items properly"Wrong return formatReturn [{json: {...}}]
"A 'json' property isn't an object"json property is primitiveWrap in object
"Cannot find module"External module not allowedCheck NODE_FUNCTION_ALLOW_EXTERNAL
"'import' may only appear at top level"ES module syntax in CJS contextUse require() instead

AI Agent Node

ErrorCauseFix
"Cannot read properties (reading 'message')"Missing message field in inputVerify chat input schema
"Cannot read properties (reading 'content')"Tool output format mismatchCheck tool return format
Model timeoutRequest too complexReduce input size or simplify

Database Nodes

ErrorCauseFix
"Connection refused"Server not accessibleCheck host/port, firewall
"Authentication failed"Wrong credentialsVerify username/password
"Unknown column"Column doesn't existCheck table schema
"Duplicate entry"Unique constraint violationHandle duplicates in logic

Part 8: Expression Validation

Common Expression Errors

ErrorCauseFix
Expression shows literal textMissing {{ }}Wrap in {{ }}
Empty result from webhookAccessing root instead of bodyUse $json.body.field
"Referenced node is unexecuted"Node hasn't runEnsure node is in execution path
"Cannot read properties of undefined"Missing propertyUse optional chaining ?.
Wrong data from $nodeItem count mismatchUse $("Node").first()

Expression Validation Checklist

code
[ ] Expression wrapped in {{ }}
[ ] All variables have $ prefix ($json, $input, etc.)
[ ] Node names match exactly (case-sensitive)
[ ] Webhook data accessed via $json.body
[ ] Optional chaining used for nested access
[ ] Default values provided for optional fields
[ ] Referenced nodes exist and will execute

Debug Expressions

javascript
// Check what keys exist
{{ Object.keys($json) }}

// Verify node reference
{{ $("Previous Node").first()?.json ? 'OK' : 'FAILED' }}

// Check type
{{ typeof $json.field }}

// Full structure
{{ JSON.stringify($json, null, 2) }}

Part 9: Workflow-Level Validation

Structural Issues

Broken Connections

json
{
  "error": "Connection from 'Transform' to 'NonExistent' - target node not found"
}

Fix:

javascript
n8n_update_partial_workflow({
  id: "workflow-id",
  operations: [{
    type: "cleanStaleConnections"
  }]
})

Circular Dependencies

json
{
  "error": "Circular dependency detected: Node A → Node B → Node A"
}

Fix: Restructure workflow to break the loop. Use Wait node if polling needed.

Multiple Trigger Nodes

json
{
  "warning": "Multiple trigger nodes found - only one will execute"
}

Fix: Remove extra triggers or split into separate workflows.

Disconnected Nodes

json
{
  "warning": "Node 'Transform' is not connected to workflow flow"
}

Fix: Connect node to workflow or remove if unused.

Import/Export Issues

IssueCauseFix
Missing nodes after importCommunity nodes not installedInstall required nodes
Credential errorsCredentials don't existRe-create credentials
Version mismatchWorkflow from newer n8nUpdate n8n or use autofix
Invalid JSONCorrupted exportUse JSON validator

Part 10: Error Handling Patterns

Pattern 1: Error Workflow (Centralized Handler)

Create a dedicated error workflow for all failures:

code
┌─────────────────────────────────────────────────┐
│ Error Workflow: [System] Centralized Handler    │
├─────────────────────────────────────────────────┤
│ Error Trigger → Switch (by workflow name)       │
│       ↓              ↓                          │
│   Critical      Non-Critical                    │
│       ↓              ↓                          │
│ Slack @channel   Log to Sheet                   │
└─────────────────────────────────────────────────┘

Error Data Available:

  • execution.id - Execution ID
  • execution.url - Link to execution
  • execution.retryOf - If retry of failed execution
  • workflow.name - Failed workflow name
  • node.name - Failed node name
  • error.message - Error details

Pattern 2: Retry On Fail (Automatic Retries)

For transient failures (API timeouts, rate limits):

javascript
// Node settings
{
  "retryOnFail": true,
  "maxTries": 3,           // 3-5 for APIs
  "waitBetweenTries": 5000 // 5-10 seconds
}

Pattern 3: Continue On Error (Batch Processing)

For processing items where some may fail:

code
Set node "On Error" to "Continue (using Error Output)"

         ↓
     ┌───┴───┐
  Success    Error
     ↓         ↓
  Process   Log/Queue
            for review

Pattern 4: Fallback LLM

For AI workflows with provider redundancy:

code
AI Agent (GPT-4)
     ↓
  [Enable Fallback Model]
     ↓
Claude (backup)

Pattern 5: Polling for Async Tasks

For long-running operations:

code
Start Task → Loop (Wait → Check Status)
                    ↓
              Is Complete?
              ↓         ↓
            Yes        No
              ↓         ↓
          Continue   Wait & Retry

Part 11: v2.0+ Validation Changes

Breaking Changes to Watch

ChangeImpactMigration
Start node removedOld workflows breakReplace with Manual Trigger
Pyodide Python removedPython Code nodes failUse Task Runners
MySQL/MariaDB removedDB connections failMigrate to PostgreSQL
Task runners default ONCode isolationUpdate env settings if needed
Sub-workflow behaviorParent receives different dataTest sub-workflow outputs
Config file permissions0600 requiredUpdate file permissions

Using the Migration Tool

  1. Go to Settings → Migration Report (v1.121.0+)
  2. Review issues by severity:
    • Critical: Will break workflows - fix first
    • Medium: May cause issues
    • Low: Recommendations
  3. Fix workflow-level issues first
  4. Then address instance-level issues
  5. Test thoroughly before upgrading

Execute Sub-Workflow Changes

Before v2.0:

  • Could call workflows with only "Manual Trigger"
  • Parent received results before child completed

After v2.0:

  • Workflows need active trigger for sub-workflow calls
  • Parent correctly waits for child completion
  • Fix: Add appropriate trigger to sub-workflows

Part 12: Recovery Strategies

Strategy 1: Start Fresh

When: Configuration is severely broken

  1. Note required fields from get_node
  2. Create minimal valid configuration
  3. Add features incrementally
  4. Validate after each addition

Strategy 2: Binary Search Debug

When: Workflow validates but executes incorrectly

  1. Remove half the nodes
  2. Validate and test
  3. If works → problem in removed nodes
  4. If fails → problem in remaining nodes
  5. Repeat until isolated

Strategy 3: Clean Stale Connections

When: "Node not found" errors

javascript
n8n_update_partial_workflow({
  id: "workflow-id",
  operations: [{
    type: "cleanStaleConnections"
  }]
})

Strategy 4: Auto-fix with Preview

When: Multiple validation errors

javascript
// Always preview first!
const preview = n8n_autofix_workflow({
  id: "workflow-id",
  applyFixes: false
});

// Review suggested fixes
console.log(preview.suggestedFixes);

// Apply if appropriate
n8n_autofix_workflow({
  id: "workflow-id",
  applyFixes: true
});

Strategy 5: Template Redeploy

When: Template workflow corrupted

javascript
// Redeploy fresh from template
n8n_deploy_template({
  templateId: 123,
  autoFix: true,
  autoUpgradeVersions: true
});

Part 13: Pre-Deployment Checklist

Node Validation

  • All nodes validated with runtime profile
  • No missing required fields
  • All values within allowed options
  • Credentials configured and tested

Expression Validation

  • All expressions wrapped in {{ }}
  • Node references match exact names
  • Webhook data accessed via $json.body
  • Optional chaining for nested access
  • Default values for optional fields

Workflow Structure

  • No broken connections
  • No circular dependencies
  • Single trigger node (or intentional multi-trigger)
  • All nodes connected to flow

Error Handling

  • Error workflow configured
  • Critical nodes have retry logic
  • Batch processing handles individual failures
  • Fallbacks for external dependencies

Testing

  • Tested with sample data
  • Edge cases handled (empty, null, errors)
  • Rate limits considered
  • Large data volumes tested

Documentation

  • Node descriptions added
  • Workflow purpose documented
  • Credential requirements noted

Part 14: Best Practices

Do

  • Validate after every significant change
  • Read error messages completely - they contain fix guidance
  • 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 when unclear about requirements
  • Preview auto-fixes before applying

Don't

  • Skip validation before activation
  • Try to fix all errors at once - leads to new errors
  • Ignore error messages - they're specific for a reason
  • Use strict during development - too noisy
  • Assume validation passed - always check result
  • Apply auto-fixes blindly - preview first
  • Deploy with unresolved errors

Validation Result Structure

javascript
{
  "valid": false,
  "errors": [
    {
      "type": "missing_required",
      "property": "channel",
      "message": "Channel name is required",
      "fix": "Provide a channel name"
    }
  ],
  "warnings": [
    {
      "type": "best_practice",
      "message": "Consider adding error handling"
    }
  ],
  "suggestions": [
    {
      "type": "optimization",
      "message": "Consider batch operations for better performance"
    }
  ]
}

Reading Results

javascript
// 1. Check valid field first
if (result.valid) {
  // ✅ Configuration is valid - proceed
} else {
  // ❌ Has errors - must fix before proceeding
}

// 2. Process errors (MUST fix)
result.errors.forEach(error => {
  console.log(`Error: ${error.property} - ${error.message}`);
  console.log(`Fix: ${error.fix}`);
});

// 3. Review warnings (SHOULD fix)
result.warnings.forEach(warning => {
  console.log(`Warning: ${warning.message}`);
});

// 4. Consider suggestions (OPTIONAL)
result.suggestions.forEach(suggestion => {
  console.log(`Suggestion: ${suggestion.message}`);
});

Resources


Last Updated: January 2026