cd /news/ai-tools/one-bad-row-killed-the-whole-batch-p… Β· home β€Ί topics β€Ί ai-tools β€Ί article
[ARTICLE Β· art-157451] src=dev.to β†— pub= topic=ai-tools verified=true sentiment=Β· neutral

One Bad Row Killed the Whole Batch: Partial-Failure Handling for n8n Loops

A developer running LLM workflows in n8n described how a single malformed lead record halted a nightly batch, leaving 453 valid leads unprocessed until a client noticed the gap. The fix, the developer writes, is to isolate per-item failures inside sub-workflows or error-handling branches, route failed items to a dead-letter list keyed by business ID, report processed/failed/skipped/retried counts separately, and retry only from the dead-letter list to avoid duplicating good records.

by read3 min views8 publishedOct 25, 2026

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.

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.

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.

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.

── more in #ai-tools 4 stories Β· sorted by recency
── more on @n8n 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/one-bad-row-killed-t…] indexed:0 read:3min 2026-10-25 Β· β€”