Error Handling
Build workflows that handle errors gracefully, recover from failures, and keep your automations running smoothly.
Time to complete: 15 minutes
Why Error Handling Matters
Errors are inevitable in automation:
| Error Source | Example |
|---|---|
| Invalid data | Missing email, wrong format |
| External services | API timeout, rate limits |
| Integration failures | Expired tokens, service down |
| Logic errors | Unexpected conditions |
Without error handling, these failures break your entire workflow. With proper handling, your workflow recovers gracefully.
Error Handling Strategies
| Strategy | When to Use |
|---|---|
| Validation | Prevent errors before they happen |
| Conditional branches | Handle known failure cases |
| Try-catch patterns | Catch unexpected errors |
| Fallback values | Provide defaults when data missing |
| Retry logic | Handle transient failures |
| Alerting | Notify team of critical failures |
Input Validation
Validate Early
Check data quality before processing:
Trigger → Validate Data → Process
│
└── Invalid → Error Handler
Common Validations
Required fields:
Condition: {{data.email}} is not empty
True → Continue
False → Return error: "Email is required"
Format validation:
Condition: {{data.email}} regex_match "^[^\s@]+@[^\s@]+\.[^\s@]+$"
True → Continue
False → Return error: "Invalid email format"
Numeric ranges:
Condition: {{data.quantity}} greater_than 0
True → Continue
False → Return error: "Quantity must be positive"
Validation Node Pattern
Use a Transform node to validate multiple fields:
const errors = [];
if (!input.email) {
errors.push("Email is required");
}
if (!input.name || input.name.length < 2) {
errors.push("Name must be at least 2 characters");
}
if (input.quantity && input.quantity < 1) {
errors.push("Quantity must be at least 1");
}
return {
valid: errors.length === 0,
errors: errors,
data: input
};
Conditional Error Handling
API Response Checking
After API calls, always check the response:
API Request Node
│
▼
Condition: {{api_1.status}} equals 200
│
┌───┴───┐
│ │
True False
│ │
▼ ▼
Process Handle Error
Multi-Status Handling
Use Multi-Condition for multiple scenarios:
Path: Success (status = 200)
→ Process response
Path: Rate Limited (status = 429)
→ Delay → Retry
Path: Auth Error (status = 401)
→ Refresh token → Retry
Path: Server Error (status >= 500)
→ Log error → Send alert
Default:
→ Log unknown error → Return failure
Fallback Values
Using Variable Fallbacks
Provide defaults for missing data:
Hello {{contact.first_name|"Valued Customer"}}!
If first_name is empty, uses "Valued Customer".
Chained Fallbacks
Try multiple sources:
{{contact.email|user.email|"no-email@placeholder.com"}}
Transform Node Fallbacks
return {
name: input.first_name || input.username || "Guest",
email: input.email || input.alternate_email,
phone: input.phone || null
};
Error Branches
Design Error Paths
Every critical operation should have an error path:
┌─────────────────┐
│ Send Email │
└────────┬────────┘
│
┌──────────────┼──────────────┐
│ │ │
Success Bounced Failed
│ │ │
▼ ▼ ▼
Continue Mark Invalid Retry/Alert
Error Response Node
Create user-friendly error responses:
{
"text": "Sorry, we couldn't process your request. Error: {{error.message}}\n\nPlease try again or contact support.",
"typing_indicator": false
}
Retry Patterns
Simple Retry
For transient failures:
API Request
│
├── Success → Continue
│
└── Fail → Delay (5 seconds) → API Request (retry)
│
├── Success → Continue
│
└── Fail → Alert + Log
Retry with Backoff
Use increasing delays:
Attempt 1: Immediate
Attempt 2: 5 seconds delay
Attempt 3: 30 seconds delay
Attempt 4: 2 minutes delay
Final: Give up + Alert
Loop-Based Retry
// In Transform node
const maxRetries = 3;
const currentAttempt = input.retry_count || 0;
return {
should_retry: currentAttempt < maxRetries,
retry_count: currentAttempt + 1,
delay_seconds: Math.pow(2, currentAttempt) * 5
};
Logging and Alerting
Log Errors
Use Transform nodes to log errors:
console.log("ERROR:", {
workflow_id: input.workflow_id,
node: "api_request_1",
error: input.error,
timestamp: new Date().toISOString(),
input_data: input.request_data
});
return {
logged: true,
error: input.error
};
Alert on Critical Failures
Send notifications when critical errors occur:
Slack Alert:
🚨 Workflow Error Alert
Workflow: {{workflow.name}}
Error: {{error.message}}
Time: {{date}} {{time}}
Contact: {{contact.email}}
Context: {{error.context}}
Email Alert:
To: ops-team@company.com
Subject: [ALERT] Workflow Failure - {{workflow.name}}
Body:
A workflow has failed and requires attention.
Error Details:
- Workflow: {{workflow.name}}
- Node: {{error.node}}
- Message: {{error.message}}
- Time: {{error.timestamp}}
Please investigate immediately.
Error Recovery Patterns
Pattern 1: Graceful Degradation
Continue with reduced functionality:
Get User Preferences
│
├── Success → Use preferences
│
└── Fail → Use defaults
│
▼
Continue workflow
Pattern 2: Compensation
Undo partial operations on failure:
Create Order
│
▼
Process Payment
│
┌───┴───┐
Success Fail
│ │
▼ ▼
Ship Cancel Order (undo)
│
▼
Notify Customer
Pattern 3: Dead Letter Queue
Save failed items for later:
Process Item
│
┌───┴───┐
Success Fail
│ │
▼ ▼
Next Save to "Failed Items" KB
Item │
▼
Alert team
Pattern 4: Circuit Breaker
Stop calling failing services:
// Check if service is healthy
if (input.consecutive_failures > 5) {
return {
status: "circuit_open",
message: "Service temporarily unavailable",
skip_call: true
};
}
// Normal operation
return {
status: "circuit_closed",
skip_call: false
};
Error Handling in Loops
Continue on Error
Process remaining items even if some fail:
Loop Configuration:
continue_on_error: true
array_source: {{items}}
Collect Errors
Track which items failed:
// After loop completes
const results = input.loop_results;
const successful = results.filter(r => r.success);
const failed = results.filter(r => !r.success);
return {
total: results.length,
successful: successful.length,
failed: failed.length,
errors: failed.map(f => ({
item: f.item,
error: f.error
}))
};
Partial Success Response
Processed {{successful}}/{{total}} items successfully.
{{#if failed}}
The following items failed:
{{#each errors}}
- {{item.name}}: {{error.message}}
{{/each}}
{{/if}}
AI Node Error Handling
Handle Empty Responses
LLM Integration
│
▼
Condition: {{llm.output}} is not empty
│
┌───┴───┐
True False
│ │
▼ ▼
Use Fallback response
output "I'm sorry, I couldn't
generate a response."
Handle KB Search Failures
KB Search
│
▼
Condition: {{kb.results.length}} greater_than 0
│
┌───┴───┐
Found Not Found
│ │
▼ ▼
RAG "I don't have information
Query about that topic."
Timeout Handling
Core Agent (max_iterations: 10)
│
▼
Condition: {{agent.success}} equals true
│
┌───┴───┐
Success Timeout/Fail
│ │
▼ ▼
Return "I'm taking longer than
output expected. Let me try
a simpler approach..."
Best Practices
Error Handling Checklist
☐ Validate inputs at start
☐ Check API responses for errors
☐ Provide fallback values
☐ Add error branches to critical nodes
☐ Implement retry for transient failures
☐ Log errors for debugging
☐ Alert on critical failures
☐ Test error paths
☐ Document error scenarios
What to Log
✅ Error type and message
✅ Timestamp
✅ Workflow and node info
✅ Input data (sanitized)
✅ Stack trace (if available)
✅ Correlation ID
❌ Don't log passwords
❌ Don't log full credit cards
❌ Don't log PII unnecessarily
User-Facing Errors
✅ "We couldn't find your order. Please check the order number."
✅ "Something went wrong. Please try again in a few minutes."
✅ "This feature is temporarily unavailable."
❌ "Error: NullPointerException at line 42"
❌ "Database connection failed"
❌ "API key invalid"
Troubleshooting
Finding Error Source
- Check execution history
- Identify failed node
- Review node input/output
- Check error message
- Enable debug mode if needed
Common Error Patterns
| Error | Likely Cause | Solution |
|---|---|---|
| "Variable not found" | Wrong path | Check variable name |
| "Cannot read property" | Null value | Add null checks |
| "API timeout" | Slow service | Add retry logic |
| "Rate limited" | Too many calls | Add delays |
| "Authentication failed" | Expired token | Refresh integration |
Next Steps
Congratulations! You've completed the Automation section. Continue exploring:
- Creating Knowledge Bases - AI-powered documentation
- Understanding Reports - Track automation performance
Quick Reference
Error Patterns
| Pattern | Use Case |
|---|---|
| Validation | Catch bad data early |
| Fallback | Provide defaults |
| Retry | Handle transient failures |
| Circuit breaker | Protect failing services |
| Dead letter | Save failed items |
Variable Fallbacks
{{field|"default"}} - String fallback
{{field1|field2|field3}} - Chain fallbacks
{{amount|0}} - Numeric fallback
Error Response Template
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Email is required",
"field": "email"
}
}