n8n 批次循環如何處理部分失敗,避免單筆錯誤中斷整批流程
One Bad Row Killed the Whole Batch: Partial-Failure Handling for n8n Loops
作者分享在 n8n 批次循環中處理部分失敗的方法,避免單筆資料錯誤中止其餘項目的處理。做法包括逐項隔離錯誤,把失敗項目及業務識別碼、錯誤和原始資料存入清單,並只重試清單中的項目。工作流應分別報告已處理、失敗、因重複而略過及已重試的數量。
One Bad Row Killed the Whole Batch: Partial-Failure Handling for n8n Loops
This is part of my build-in-public series on running LLM workflows in n8n in production. Everything here is from real templates I sell and support — the mistakes are mine, the fixes are tested.
The batch failed at row 47. Rows 48 to 500 never ran
A nightly workflow of mine processed a batch of new leads: enrich each one, score it, write it to the CRM. One night a single lead had a malformed phone field, the enrichment node threw, and the execution stopped. The other 453 leads sat unprocessed until the next morning, when a client asked why half the day's leads were missing.
Nothing about this was exotic. A batch loop that stops on the first error is the default behavior in most workflow tools, and it turns one bad record into a silent outage for every record behind it. The error itself was visible — the execution log showed the failure. What was invisible was the cost: hundreds of good records that never got processed because they happened to queue behind a bad one.
The fix is not "validate better." You will never validate away every malformed record from a source you do not control. The fix is to decide, per item, what failure means — and to make that decision before the loop runs, not after it stops.
Three rules I now build into every batch loop
First, isolate failures to the item that caused them. In n8n this means the per-item work runs where an error cannot kill the loop: a sub-workflow executed per item, or an error-handling branch that catches the failure and returns it as data instead of throwing. The loop itself never sees an exception — it sees a result, either success or a structured failure record. Once a bad row produces a row in a failure list instead of a stopped execution, the batch always completes, and "complete" stops being a lie.
Second, collect failures into a dead-letter list, not a log line. A failed item goes into a table with the item's business key, the error, and the raw payload — everything needed to reprocess it without re-running the whole batch. My rule: a batch that ends with failures still reports success for the good items and a separate count for the failed ones, and the failed list is the input to a retry workflow, not a note for someone to read someday. If a failure cannot be retried from the list alone, the list is missing a field, and that is the bug to fix.
Third, report four numbers, not one status. Processed, failed, skipped as duplicates, and retried. When failed jumps from zero to one, that is a data problem worth one look. When failed jumps to forty, that is a schema change upstream, and I want to know before the client does. A batch that reports only "done" hides exactly the distinction between "everything worked" and "everything after row 47 never ran" — which is the distinction the whole report exists to make.
The retry rule that keeps this honest
Retrying the whole batch is how a partial failure becomes a duplicate problem: the good items run twice. So retries run against the dead-letter list only, keyed by the business id, with the same dedupe check the main loop uses. A retried item that succeeds is marked done; one that fails again stays on the list with its new error. Nothing ever re-enters the main batch, and the main batch never re-processes a good item because a bad one showed up late.
The principle is simple: a batch loop's job is to finish the batch, not to stop at the first surprise. One bad row should cost you one row, one entry in a list, and one retry — never the 453 good rows standing behind it.
I'm building AI Automation Lab — production-ready n8n workflow templates. The free AI Hook Generator shows how I structure real workflows; my open-source templates live at github.com/zhp910318/n8n-ai-automation-lab.
來源:DEV Community · dev.to