Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/czlonkowski/n8n-skills/llms.txt

Use this file to discover all available pages before exploring further.

Validation Expert

Expert guide for interpreting and fixing n8n validation errors.
Validate early, validate often. Validation is iterative — expect 2–3 validate → fix cycles. The average is 23 seconds thinking about errors and 58 seconds fixing them per cycle.

The Validation Loop

From real telemetry: 7,841 occurrences of this exact pattern:
1. Configure node

2. validate_node  (23s thinking about errors)

3. Read error messages carefully

4. Fix errors

5. validate_node again  (58s fixing)

6. Repeat until valid  (usually 2–3 iterations)

Example Loop

// Iteration 1
let config = {
  resource: "channel",
  operation: "create"
};

const result1 = validate_node({
  nodeType: "nodes-base.slack",
  config,
  profile: "runtime"
});
// → Error: Missing "name"

// ⏱ 23 seconds thinking...

// Iteration 2
config.name = "general";

const result2 = validate_node({
  nodeType: "nodes-base.slack",
  config,
  profile: "runtime"
});
// → Error: Missing "text"

// ⏱ 58 seconds fixing...

// Iteration 3
config.text = "Hello!";

const result3 = validate_node({
  nodeType: "nodes-base.slack",
  config,
  profile: "runtime"
});
// → Valid! ✅
Multiple validation iterations are completely normal. Don’t try to fix all errors at once — address them one at a time.

Validation Profiles

Choose the right profile for your development stage:
Use when: Quick checks during active editingValidates: Required fields only, basic structurePros: Fastest, most permissiveCons: May miss real issues
validate_node({
  nodeType: "nodes-base.slack",
  config: {},
  mode: "minimal"
})
// Returns: missingRequiredFields array

Validation Result Structure

{
  "valid": false,
  "errors": [
    {
      "type": "missing_required",
      "property": "channel",
      "message": "Channel name is required",
      "fix": "Provide a channel name (lowercase, no spaces, 1-80 characters)"
    }
  ],
  "warnings": [
    {
      "type": "best_practice",
      "property": "errorHandling",
      "message": "Slack API can have rate limits",
      "suggestion": "Add onError: 'continueRegularOutput' with retryOnFail"
    }
  ],
  "suggestions": [
    {
      "type": "optimization",
      "message": "Consider using batch operations for multiple messages"
    }
  ],
  "summary": {
    "hasErrors": true,
    "errorCount": 1,
    "warningCount": 1,
    "suggestionCount": 1
  }
}

Error Severity Levels

SeverityBlocks Execution?Action Required
ErrorYes — must fix before activationFix immediately
WarningNo — workflow can run but may have issuesFix for production
SuggestionNo — optional improvementFix if convenient

Common Error Catalog

What it means: A field that is required for the selected operation is absent.How to fix:
  1. Use get_node to see what fields the operation requires
  2. Add the missing field with an appropriate value
// Error
{
  "type": "missing_required",
  "property": "channel",
  "message": "Channel name is required",
  "fix": "Provide a channel name"
}

// Fix
config.channel = "#general";
What it means: The value provided doesn’t match the list of allowed options.How to fix:
  1. Read the error message for the allowed values list
  2. Use get_node to see all options
// Error
{
  "type": "invalid_value",
  "property": "operation",
  "message": "Operation must be one of: post, update, delete",
  "current": "send"
}

// Fix
config.operation = "post";  // Use a valid operation
What it means: The value is the right field but the wrong type (e.g., string instead of number).
// Error
{
  "type": "type_mismatch",
  "property": "limit",
  "message": "Expected number, got string",
  "current": "100"
}

// Fix
config.limit = 100;  // Number, not string
What it means: An expression field has invalid {{}} syntax.
// Error
{
  "type": "invalid_expression",
  "property": "text",
  "message": "Invalid expression: $json.name",
  "current": "$json.name"
}

// Fix — add {{}} wrapper
config.text = "={{$json.name}}";
See the Expression Syntax skill for the full expression guide.
What it means: An expression references a node that doesn’t exist in the workflow.
// Error
{
  "type": "invalid_reference",
  "property": "expression",
  "message": "Node 'HTTP Requets' does not exist",
  "current": "={{$node['HTTP Requets'].json.data}}"
}

// Fix — correct the typo
config.expression = "={{$node['HTTP Request'].json.data}}";

Auto-Sanitization System

Auto-sanitization runs automatically on ALL nodes during ANY workflow update (create or update_partial).

What It Fixes Automatically

Operators that compare two values: equals, notEquals, contains, notContains, greaterThan, lessThan, startsWith, endsWithFix: Removes singleValue property (binary operators should not have it)
// Before (wrong)
{
  "type": "boolean",
  "operation": "equals",
  "singleValue": true   // ❌ Binary operators don't need this
}

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

What Auto-Sanitization Cannot Fix

IssueCauseSolution
Broken connectionsReferences to deleted nodesUse cleanStaleConnections operation
Branch count mismatches3 Switch rules but only 2 connectionsAdd missing connections or remove rules
Paradoxical corrupt statesAPI returns corrupt, rejects updatesMay require manual database intervention

Auto-Fix Tool

For bulk fixes beyond auto-sanitization:
// Preview fixes first (default: doesn't apply)
n8n_autofix_workflow({
  id: "workflow-id",
  applyFixes: false,
  confidenceThreshold: "medium"  // high, medium, low
})

// Apply fixes after review
n8n_autofix_workflow({
  id: "workflow-id",
  applyFixes: true
})
Fix types the auto-fix tool handles:
  • expression-format — Fix expression syntax
  • typeversion-correction — Correct typeVersion
  • error-output-config — Fix error output settings
  • webhook-missing-path — Add missing webhook paths
  • typeversion-upgrade — Upgrade to latest version
  • version-migration — Apply version migrations

False Positives Guide

Some validation warnings are technically “wrong” but acceptable in context.
When it’s a false positive: Simple workflows where failures are obvious, testing or development workflows, and non-critical notification workflows.When you should fix it: Production workflows handling important data or payments.
When it’s a false positive: APIs with their own built-in retry logic, idempotent operations where double-execution is harmless, and manual trigger workflows run by a human.When you should fix it: Flaky external services in production automation.
When it’s a false positive: Internal APIs with no rate limits, low-volume workflows (few executions per day), and APIs that enforce rate limiting server-side.When you should fix it: Public APIs with strict rate limits and high-volume automated workflows.
When it’s a false positive: Small, known-size datasets, aggregation queries (COUNT, SUM) that scan the full table by design, and development/testing environments.When you should fix it: Production queries on large tables.
To reduce false positives in AI-generated configurations:
validate_node({
  nodeType: "nodes-base.slack",
  config: {...},
  profile: "ai-friendly"  // Fewer false positives
})

Workflow Validation

// Validate the full workflow structure
validate_workflow({
  workflow: {
    nodes: [...],
    connections: {...}
  },
  options: {
    validateNodes: true,
    validateConnections: true,
    validateExpressions: true,
    profile: "runtime"
  }
})

// Validate by workflow ID (requires n8n API)
n8n_validate_workflow({
  id: "workflow-id",
  options: {profile: "runtime"}
})

Common Workflow-Level Errors

ErrorCauseFix
Connection from 'X' to 'Y' - target node not foundStale connection to a deleted nodeUse cleanStaleConnections operation
Circular dependency detected: A → B → ALoop in workflowRestructure to remove the cycle
Multiple trigger nodes foundMore than one triggerRemove extra triggers or split into separate workflows
Node 'X' is not connected to workflow flowOrphaned nodeConnect it or delete it

Recovery Strategies

When: Configuration is severely broken or corrupted.
// 1. Get required fields
get_node({nodeType: "nodes-base.slack", mode: "minimal"})

// 2. Create minimal valid config
const config = {resource: "message", operation: "post", channel: "#general", text: "Hi"};

// 3. Validate
validate_node({nodeType: "nodes-base.slack", config, profile: "runtime"})

// 4. Add features incrementally, validating after each addition

Profile Selection by Stage

Development StageRecommended Profile
Initial editing / explorationminimal
Active developmentruntime
AI-generated configsai-friendly
Pre-deployment checkruntime
Critical production deploymentstrict

Best Practices

Do

  • Validate after every significant change
  • Read error messages completely before fixing
  • Fix errors one at a time iteratively
  • Check the valid field — don’t assume it passed
  • Trust auto-sanitization for operator issues
  • Use get_node when the required fields aren’t obvious

Don't

  • Skip validation before activation
  • Try to fix all errors simultaneously
  • Use strict profile during development
  • Manually fix auto-sanitization issues
  • Deploy with unresolved error severity issues
  • Ignore all warnings (some are genuinely important)

Build docs developers (and LLMs) love