When processing batches (importing records, sending emails, updating a CRM), some items will succeed and others will fail.
When processing batches (importing records, sending emails, updating a CRM), some items will succeed and others will fail. Track both counts, handle them separately, and produce a clear execution summary. This prevents the all-or-nothing problem where one bad record kills the entire batch.
Real-world example: A nightly workflow imports 500 contacts from a CSV into HubSpot. 12 contacts have invalid email addresses and fail. The other 488 should still be imported, and the 12 failures should be reported.
// Code node: "Process Batch Results"
// Place after a node with "Continue on Fail" enabled
const allItems = $input.all();
const results = {
total: allItems.length,
succeeded: 0,
failed: 0,
successItems: [],
failedItems: []
};
for (const item of allItems) {
if (item.json.error) {
results.failed++;
results.failedItems.push({
originalData: item.json,
error: item.json.error.message || 'Unknown error',
index: results.succeeded + results.failed - 1
});
} else {
results.succeeded++;
results.successItems.push(item.json);
}
}
results.successRate = Math.round(
(results.succeeded / results.total) * 100
);
return [{
json: results
}];
```text
Generate a batch processing report:
```javascript
// Code node: "Generate Batch Report"
const r = $input.first().json;
const report = {
summary: `Batch complete: ${r.succeeded}/${r.total} succeeded (${r.successRate}%)`,
succeeded: r.succeeded,
failed: r.failed,
total: r.total,
successRate: r.successRate,
needsAttention: r.failed > 0,
failedItemsSample: r.failedItems.slice(0, 10).map(f => ({
error: f.error,
data: JSON.stringify(f.originalData).substring(0, 200)
}))
};
// Determine if this batch needs an alert
if (r.successRate < 90) {
report.alertLevel = 'critical';
report.alertMessage = `Batch success rate below 90%: only ${r.successRate}%`;
} else if (r.failed > 0) {
report.alertLevel = 'warning';
report.alertMessage = `${r.failed} items failed in batch`;
} else {
report.alertLevel = 'info';
report.alertMessage = 'All items processed successfully';
}
return [{ json: report }];
```text
```yaml
Routing after the report:
[Batch Report] --> [Switch: alertLevel]
|
+----------+----------+
| | |
[critical] [warning] [info]
| | |
[Slack + [Slack [Log to
DLQ for alert] DB only]
failed
items]
```text
This gives you full visibility into batch health. A 95% success rate might be acceptable; a 50% success rate triggers immediate investigation.
**Related:** [Use "Pin Data" to Freeze Node Output](../testing-and-debugging/01-use-pin-data-to-freeze-node-output.md) | [Break Large Workflows into Sub-Workflows](../workflow-architecture/01-break-large-workflows-into-sub-workflows.md)
I build production n8n and Cloudflare automation for teams — the same engineering behind HarperFlow. Fixed-price, escrow-protected, US-based.