Debug & Error Handling
Ch04 Debug & Error Handling
A workflow that works in development doesn't guarantee production stability. Network timeouts, API rate limits, unexpected data formats โ any of these can interrupt your carefully designed automation. This chapter systematically covers n8n's debugging toolchain and error handling strategies to make your workflows production-grade.
Execution Log Panel: See Exactly What's Flowing Between Nodes
n8n's most powerful debugging tool is the execution log panel. After any workflow run, clicking any node shows that node's Input and Output data โ down to every JSON field.
Useful view modes:
- Schema view: Default key-value structure โ best for quick field inspection
- JSON view: Raw JSON โ best for copying data or inspecting nested structures
- Table view: Multiple items as a table โ best for comparing fields across items
- Binary view: Binary data from file nodes (PDF, image downloads, etc.)
Tip: Click any field value in the execution log to copy it directly. For complex expression paths (e.g.,
data.items[0].price), find the actual data structure in the execution log first, then build your expression.
Pin Data: Lock Test Data to Skip Slow Upstream Steps
During development, every debug cycle means waiting for the trigger, waiting for RSS data, waiting for API responsesโฆ Pin Data eliminates this friction.
How to use it:
- Execute the workflow once to generate real output from a node
- In the node's Output panel header, click the Pin ๐ button
- The pinned node shows a pin icon; subsequent runs return the pinned data without re-executing the node
- Downstream nodes can be debugged against the fixed data without re-triggering the upstream
Classic use case: When tuning an OpenAI prompt, Pin the RSS and Code nodes. Each prompt iteration tests instantly against fixed data โ no RSS re-fetch, no wasted API tokens.
Error Trigger Node: Global Error Capture
n8n provides a special Error Trigger node that fires whenever a designated workflow fails. Use it to build a dedicated "error alert workflow".
Setup steps:
- Create a new workflow called "Error Alert"
- Add an Error Trigger node as the trigger (no configuration needed)
- Build your alert logic in subsequent nodes (Slack, email, PagerDuty, etc.)
- In your main workflow's Settings, set Error Workflow to "Error Alert"
When the main workflow fails, Error Trigger fires automatically with this data structure:
{
"workflow": {
"id": "abc123",
"name": "Hacker News Daily Digest"
},
"execution": {
"id": "exe456",
"url": "https://your-n8n.com/execution/exe456",
"error": {
"message": "Request failed with status code 429",
"description": "Too Many Requests - Rate limit exceeded",
"context": {
"node": { "name": "OpenAI Summary" }
}
},
"lastNodeExecuted": "OpenAI Summary"
}
}
Continue on Fail: Node-Level Fault Tolerance
Sometimes you want the workflow to continue processing other items even if one node fails for a specific item. Configure this in the node's Settings tab:
| Option | Behavior | Best For |
|---|---|---|
| Stop And Error (default) | Entire workflow stops on error | Critical nodes where errors must not be silently skipped |
| Continue | Skips the failing item; continues next item | Batch processing where some items may fail |
| Continue (using error output) | Error info becomes output item data | When you need to track which items failed |
Caution: Use Continue carefully โ silently ignoring critical node failures can cause data inconsistency or missed processing. Always combine with logging to ensure failed items are traceable.
Retry Configuration
For transient failures caused by network jitter or temporary API rate limits, auto-retry is the simplest solution. In node settings:
- Retry On Fail: Enable retry
- Max Tries: Maximum retry attempts (3โ5 recommended)
- Wait Between Tries: Delay in milliseconds between retries
Retry vs Error handling: Retries are appropriate for idempotent operations (same result on repeated execution) like GET requests and database reads. For non-idempotent operations (payments, sending emails), avoid blind retries โ they can cause duplicate actions.
Alert Notifications: Auto-Send Alerts on Failure
// Insert this Code node between Error Trigger and HTTP Request
// Formats error info into a readable alert
const error = items[0].json;
const now = new Date().toLocaleString('en-US', { timeZone: 'America/New_York' });
const alertMessage = {
workflowName: error.workflow.name,
errorNode: error.execution.error?.context?.node?.name || 'Unknown',
errorMessage: error.execution.error?.message || 'Unknown error',
executionUrl: error.execution.url,
timestamp: now,
suggestion: error.execution.error?.message?.includes('429')
? 'Rate limit hit โ check call frequency or upgrade API plan'
: error.execution.error?.message?.includes('401')
? 'Auth failure โ check if API key is expired'
: 'Check execution log for details',
};
return [{ json: alertMessage }];
Best practice: Configure an error notification workflow for every production workflow, and include a direct link to the execution record in the alert message (
{{ $json.execution.url }}). A single click from the alert takes you directly to the full error context โ dramatically shortening investigation time.
Common Error Types and Resolution Strategies
HTTP 401 / 403
API key wrong or insufficient permissions. Verify the Credential, confirm the key hasn't expired, check the key's permission scope.
HTTP 429
Rate limited. Enable retry with wait time, add delay in Code node (await new Promise(r => setTimeout(r, 1000))), or upgrade the API plan.
HTTP 500 / 502
Target server internal error. Usually transient โ enable retry. If persistent, check the target service's status page.
Expression Error
Expression references a non-existent field. Inspect the upstream node's actual output structure. Use optional chaining to avoid null errors: {{ $json.user?.name }}.
Timeout Error
HTTP Request timed out. Increase the Timeout value in node settings, or optimize the target API's response time.
JSON Parse Error
Response body is not valid JSON. Check the HTTP Request's Response Format setting โ may need to switch to Text and parse manually.