n8n-error-handling – skill Thiết kế & UI cho agent AI
Thiết kế lỗi n8n dễ thấy, có cấu trúc và có thể phục hồi, dùng error output, retry, workflow Error Trigger và HTTP error response.
Cài skill n8n-error-handling bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/n8n-error-handling-5c8cf.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /n8n-error-handling – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/n8n-error-handling-5c8cf.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $n8n-error-handling – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/n8n-error-handling-5c8cf.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /n8n-error-handling – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/n8n-error-handling-5c8cf.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /n8n-error-handling – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
n8n Error Handling
Operational boundaries
Discover actual n8n tool schemas and node versions: this tree bundles documents, not an MCP server. Drafting does not authorize changing or activating production workflows, sending alerts or replaying writes. Retry only operations proven idempotent or protected by durable deduplication; ambiguous timeouts may have committed. An Error Trigger is not a process-crash/OOM availability guarantee: use independent platform monitoring. It does not fire for manual editor executions. Node error output positions depend on node output layout; verify rather than assuming index 1 for multi-output nodes. Use structured error codes rather than regex matches on untrusted text to decide status or retries.
When to Use
Use this skill for unattended workflows, webhook/API response contracts, retry design, error outputs, Error Trigger workflows, alerting, or any path where failure must be visible and recoverable.
Make retries bounded and idempotent, especially for sends, payments, and writes. Redact credentials, personal data, request bodies, and stack details from caller-facing responses and alerts; expose only the minimum diagnostic context required.
By default, when an n8n node throws, the whole workflow halts. For an interactive run you're watching, that's fine — you see the red node and fix it. For anything unattended (a webhook API, a cron job, a queue worker, an agent tool), it's the wrong default: the caller gets a timeout or an empty 500, the operator gets no alert, and the symptom is "the integration just stopped working" with no log and no clue.
This skill is about making failures loud, structured, and recoverable — and, best case, self-healing so transient blips never reach a human at all.
The two ideas that prevent most silent failures:
- Per-node error outputs — a node's failure routes down a second output you control, instead of killing the run.
- A workflow-level error workflow — a catch-all that fires for anything that escapes per-node handling (timeouts, crashes between nodes, unwired failures).
---
When you actually need this
| Workflow shape | Error handling posture |
|---|---|
| Webhook / API (anything with Respond to Webhook) | Required. Every fallible node's error output wired; status code matches cause. |
| Scheduled / cron / queue worker / agent tool (unattended) | Required. A workflow-level error workflow, plus bounded retries on retry-safe nodes. |
| Internal one-off you run and watch yourself | Optional. Default onError: "stopWorkflow" is fine — you'll see the red node and re-run. |
The dividing line: if anyone other than you sees the output — a downstream system, an end user, an on-call engineer — the failure has to be handled, not swallowed. If you're the only watcher and the cost of failure is "I notice and re-run", looser is fine.
---
The #1 silent trap: per-node error output is a TWO-step setup
This is the single most common way an n8n workflow "handles" errors while actually swallowing them. Routing a node's failure to a handler takes two changes, and doing only one looks complete but misbehaves:
1. Set onError: "continueErrorOutput" on the node. This is what *creates* the second output. Without it, main[1] doesn't exist no matter what you wire.
2. Wire that error output (connections.<node>.main[1], i.e. sourceIndex: 1) to a real handler. Without a target, the error data is emitted into the void.
Get one without the other and you hit a failure mode:
| What you did | What happens at runtime |
|---|---|
| onError set, error output not wired | Error data is silently discarded. Downstream doesn't fire. The dashboard shows the run as succeeded. Worst case — no error logged anywhere. |
| Error output wired, onError not set | The slot never fires; the handler is unreachable. On failure the workflow just halts (default stopWorkflow). |
| Both done | Failure routes down main[1] to your handler. ✅ |
Doing both with n8n_update_partial_workflow
// 1) Turn on the error output (creates main[1])
{ type: "updateNode", nodeName: "HTTP Request",
changes: { onError: "continueErrorOutput" } }
// 2) Wire the error output to a handler. sourceIndex: 1 = the error output.
{ type: "addConnection",
source: "HTTP Request",
target: "Handle Error",
sourceIndex: 1 }sourceIndex: 0 is the success path, sourceIndex: 1 is the error path. (For IF nodes the aliases branch: "true"/"false" map to index 0/1; for a generic fallible node, use the explicit sourceIndex: 1.)
Then verify. This trap doesn't surface in validate_workflow — a half-wired error output validates clean. Pull the workflow with n8n_get_workflow and confirm both halves:
- The node's
onErroris"continueErrorOutput". connections["HTTP Request"].main[1]contains your handler.
Valid onError values:
| Value | Effect |
|---|---|
| "stopWorkflow" (default) | Error halts the whole workflow. |
| "continueRegularOutput" | Error item flows out the normal output. Rare, usually wrong — downstream gets error-shaped data and keeps going. |
| "continueErrorOutput" | Error item flows out the separate error output (main[1]). The one you wire. |
Full failure-mode catalog, fan-in/fan-out shapes, and verification: references/NODE_ERROR_OUTPUTS.md.
---
Self-healing first: retryOnFail before you wire error paths
Before you build error branches, absorb the transient failures so they never reach those branches. On a network node only after verifying its retry safety — HTTP Request, comms (Gmail/Slack/Discord), databases, AI nodes, third-party integrations — set node-level retry:
{ type: "updateNode", nodeName: "HTTP Request",
changes: {
retryOnFail: true,
maxTries: 3,
waitBetweenTries: 5000 // ms
} }Why this comes first: a 429 or a brief upstream hiccup will retry and usually succeed on its own. The error output then fires only on *real, persistent* failures — so your 5xx responses and on-call alerts reflect actual problems instead of noise.
Engine limits to know: retry fires on any error (there's no per-status-code filter), maxTries caps at 5, and waitBetweenTries caps at 5000ms — so 5000 is both the max and a sensible default. See n8n-node-configuration (NODE_FAMILY_GOTCHAS.md) for node-specific notes.
---
API workflows: the canonical shape
A webhook-triggered workflow that responds to its caller has one rule that overrides everything else: no hanging branches. Every path — success and every error — must end at a Respond to Webhook, or the caller sits there until it times out.
Webhook (responseMode: "responseNode")
├── validate input → process → Respond (200, body)
└── (any fallible node's error output → sourceIndex 1)
→ Respond (4xx/5xx, structured error body)
→ optional: log redacted diagnostics privately / notifyThree things make this work:
1. Fan-in to one error responder. Many fallible nodes can route their main[1] to a single Respond node. Keeps the graph readable.
2. **Validation failures (4xx) are checked *upstream*, not via error outputs.** A missing field isn't a node *crashing* — it's an expected outcome with a known response. Branch on it with IF/Switch (or the schema validator below) and return 400/401/403/404 directly. Error outputs are for *unexpected* failures (5xx).
3. responseCode defaults to 200 — even on error branches. This is its own silent trap (see references/RESPONSE_SHAPES.md and n8n-node-configuration at ../n8n-node-configuration/references/NODE_FAMILY_GOTCHAS.md): an error branch that returns 200 with an error body looks like success to the caller's HTTP client, so their error handling never fires. Set responseCode explicitly on every Respond node.
Input validation: the Set-node schema validator
For any endpoint doing structured input validation, run the check as an IIFE inside a single Set node rather than a chain of IF/Switch nodes per field. One node validates the whole payload, returns { valid, validationError, details, requiredSchema }, and an IF branches on valid → your logic (200) or a 400 Respond that echoes the schema back so the caller can self-correct. Choose a validator that enforces the stated schema; no performance comparison is established here. The full pattern, the constraint cookbook, and the expression-escaping gotchas live in references/API_WORKFLOWS.md.
---
Response shapes: map cause → status code
A 5xx with text/plain "Internal Server Error" is technically an error response and practically useless. And not every failure is a 5xx. **Match the status code to *why* the request failed**, because the caller branches on it: their monitoring alerts on 5xx (your fault) but not 4xx (their fault), and 5xx suggests "retry" while 4xx suggests "don't".
**The c
… (nội dung đầy đủ có trong gói tải về)
Skill liên quan
- neo-brutalism – Hướng dẫn triển khai Neo-Brutalism cho Web và App. Kích hoạt khi người dùng muốn viền…
- nerdzao-elite – Quy trình kỹ thuật phần mềm và thiết kế sản phẩm, đóng vai Senior Product Designer. Quy…
- nerdzao-elite-gemini-high – Chế độ Elite Coder + UX Pixel-Perfect được tối ưu riêng cho Gemini 3.1 Pro High. Quy…
- neumorphism – Hướng dẫn triển khai Neumorphism (Soft UI) cho Web và App. Kích hoạt khi người dùng muốn…
- nosql-expert – Hướng dẫn chuyên sâu cho cơ sở dữ liệu NoSQL phân tán (Cassandra, DynamoDB). Tập trung…
- not-a-vibe-coder – Biến các prompt mơ hồ thành 8 tệp lập kế hoạch có cấu trúc cho dự án mới hoàn toàn…
- nsfw-ai-spicyapi – Tạo ảnh người lớn (18+), clip image-to-video và chỉnh sửa ảnh qua SpicyAPI, với báo giá…
- obsess – Chế độ cầu toàn cho một mục tiêu: thử nghiệm có kiểm tra trên chi tiết UI hoặc hot path…