<p><img class="alignnone size-full wp-image-4355" src="https://flowgenius.in/wp-content/uploads/2026/01/Child-10-Cluster-9.png" alt="" /></p>
<p style="text-align: center;">Step by Step Guide to solve n8n Merge Node Conflict Error</p>
<p> </p>
<hr />
<p> </p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Who this is for:</strong> n8n developers who use the <strong>Merge</strong> node to combine two or more data streams and need a reliable way to handle duplicate keys. <strong>We cover this in detail in the</strong> <a href="https://flowgenius.in/n8n-node-errors-troubleshooting/">n8n Node Specific Errors Guide.</a></p>
<hr style="margin: 50px 0; border: none;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">Quick Diagnosis</h2>
<p style="margin-bottom: 2em; line-height: 1.9;">The “Merge node conflict error” appears when two input items share the same <strong>key field</strong> while the node is in <strong>“Merge By”</strong> mode and the <strong>Conflict handling</strong> option is set to <strong>“Throw error on conflict”</strong>.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">Quick fix</h3>
<ol style="margin-bottom: 2em; line-height: 1.9;">
<li>Open the Merge node → <strong>Mode</strong> = <em>Merge By</em>.</li>
<li>Choose a <strong>Key Field</strong> that is guaranteed to be unique (e.g., <code>id</code>, <code>uuid</code>).</li>
<li>If uniqueness cannot be guaranteed, change <strong>Conflict handling</strong> to <strong>“Overwrite”</strong> or <strong>“Skip”</strong>.</li>
<li>(Optional) Add a <strong>Set</strong> node before the Merge to generate a unique composite key: <code>{{$json["id"]}}_{{$index}}</code>.</li>
</ol>
<p style="margin-bottom: 2em; line-height: 1.9;">Re‑run the workflow – the error disappears.</p>
<hr style="margin: 50px 0; border: none;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">1️⃣ Why the Merge node throws a conflict error</h2>
<p><strong>If you encounter any</strong> <a href="https://flowgenius.in/n8n-slack-node-rate-limit/">n8n slack node rate limit</a><strong> resolve them before continuing with the setup.</strong></p>
<p> </p>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="padding: 13px; border: 1px solid #ddd;">Situation</th>
<th style="padding: 13px; border: 1px solid #ddd;">Node behaviour</th>
<th style="padding: 13px; border: 1px solid #ddd;">Result</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Two items share the same <strong>Key Field</strong> while <strong>Mode = Merge By</strong></td>
<td style="padding: 13px; border: 1px solid #ddd;">The node tries to merge the items into a single record</td>
<td style="padding: 13px; border: 1px solid #ddd;">Default <strong>Conflict handling = Throw error</strong> → workflow stops</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;"><strong>Mode = Append</strong> with duplicate items</td>
<td style="padding: 13px; border: 1px solid #ddd;">Items are simply concatenated</td>
<td style="padding: 13px; border: 1px solid #ddd;">No conflict check – duplicates remain</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;"><strong>Mode = Keep Key</strong> with non‑unique keys</td>
<td style="padding: 13px; border: 1px solid #ddd;">First occurrence is kept, later ones ignored</td>
<td style="padding: 13px; border: 1px solid #ddd;">No error, but data may be silently dropped</td>
</tr>
</tbody>
</table>
<blockquote style="margin: 2em 0; padding-left: 1em; border-left: 4px solid #ddd; font-style: italic;">
<p style="margin-bottom: 0; line-height: 1.9;"><strong>EEFA note:</strong> The error is intentional – it protects you from unintentionally overwriting data.</p>
</blockquote>
<hr style="margin: 50px 0; border: none;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">2️⃣ Merge node modes & conflict handling</h2>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="padding: 13px; border: 1px solid #ddd;">Mode</th>
<th style="padding: 13px; border: 1px solid #ddd;">What it does</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;"><strong>Append</strong></td>
<td style="padding: 13px; border: 1px solid #ddd;">Concatenates the two input arrays (no conflict check).</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;"><strong>Merge By</strong></td>
<td style="padding: 13px; border: 1px solid #ddd;">Merges items that share the same <strong>Key Field</strong>.</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;"><strong>Keep Key</strong></td>
<td style="padding: 13px; border: 1px solid #ddd;">Keeps the first occurrence of each key, discarding later ones.</td>
</tr>
</tbody>
</table>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="padding: 13px; border: 1px solid #ddd;">Conflict handling (only for <strong>Merge By</strong>)</th>
<th style="padding: 13px; border: 1px solid #ddd;">Behaviour</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;"><strong>Throw error</strong> (default)</td>
<td style="padding: 13px; border: 1px solid #ddd;">Stops execution on duplicate keys.</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;"><strong>Overwrite</strong></td>
<td style="padding: 13px; border: 1px solid #ddd;">Newer item replaces the older one.</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;"><strong>Skip</strong></td>
<td style="padding: 13px; border: 1px solid #ddd;">Keeps the first item, discards duplicates.</td>
</tr>
</tbody>
</table>
<blockquote style="margin: 2em 0; padding-left: 1em; border-left: 4px solid #ddd; font-style: italic;">
<p style="margin-bottom: 0; line-height: 1.9;"><strong>Best practice:</strong> Use <strong>Overwrite</strong> only when you have a deterministic rule (e.g., latest timestamp). Otherwise prefer <strong>Skip</strong> and log the conflict. <strong>If you encounter any</strong> <a href="https://flowgenius.in/n8n-google-sheets-node-rate-limit/">n8n google sheets node rate limit</a><strong> resolve them before continuing with the setup.</strong></p>
</blockquote>
<hr style="margin: 50px 0; border: none;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">3️⃣ Pre‑run checklist (micro‑summary)</h2>
<p style="margin-bottom: 2em; line-height: 1.9;">Before you execute the workflow, verify the following items to avoid conflicts.</p>
<ul style="margin-bottom: 2em; line-height: 1.9;">
<li><strong>Key field</strong> is selected and truly unique across <em>all</em> inputs.</li>
<li><strong>Conflict handling</strong> matches your business rule (Overwrite / Skip).</li>
<li>No <strong>null/undefined</strong> values in the key field (add a fallback if needed).</li>
<li>Input batch size respects server limits – use <strong>SplitInBatches</strong> for large sets.</li>
<li><strong>Logging</strong>: capture skipped items for audit.</li>
</ul>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">- [ ] Unique key field selected
- [ ] Conflict handling set appropriately
- [ ] No null keys (add fallback)
- [ ] Batch size within limits
- [ ] Skipped items logged
</pre>
<hr style="margin: 50px 0; border: none;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">4️⃣ Step‑by‑step resolution guide</h2>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.1 Identify the conflicting key</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">Add a <strong>Set</strong> node that copies the candidate key to a visible field (<code>conflictKey</code>).</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{
"name": "Expose Key",
"type": "n8n-nodes-base.set",
"parameters": {
"values": {
"string": [
{
"name": "conflictKey",
"value": "={{$json[\"id\"]}}"
}
]
}
}
}
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">Run the workflow, open <strong>Execution → View Execution</strong>, and filter on <code>conflictKey</code>. Duplicate values are the culprits.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.2 Ensure a truly unique key</h3>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Option A – Use an existing unique identifier</strong> (e.g., <code>uuid</code>).</p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Option B – Create a composite key</strong> with a Set node:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{{ $json["email"] + "_" + $json["createdAt"] }}
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">Reference this new field (<code>compositeKey</code>) in the Merge node’s <strong>Key Field</strong>.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.3 Adjust conflict handling</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">Open the Merge node and select the appropriate option:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{
"mode": "mergeBy",
"keyField": "uid",
"conflictHandling": "skip" // or "overwrite"
}
</pre>
<ul style="margin-bottom: 2em; line-height: 1.9;">
<li><strong>Skip</strong> – keeps the first occurrence, discards later duplicates.</li>
<li><strong>Overwrite</strong> – newer item replaces the older one (use with a deterministic rule).</li>
</ul>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.4 (Optional) Split large batches before merging</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">When processing thousands of records, split the inputs to stay within memory limits:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{
"name": "Split Large Batch",
"type": "n8n-nodes-base.splitInBatches",
"parameters": { "batchSize": 500 }
}
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">Merge each batch individually, then concatenate the results with a <strong>Merge (Append)</strong> node.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.5 Minimal working example (broken into bite‑size snippets)</h3>
<h4 style="margin-bottom: 45px; line-height: 1.3;">4.5.1 Fetch two data streams</h4>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{
"name": "HTTP Get Users",
"type": "n8n-nodes-base.httpRequest",
"parameters": { "url": "https://api.example.com/users" }
}
</pre>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{
"name": "HTTP Get Updates",
"type": "n8n-nodes-base.httpRequest",
"parameters": { "url": "https://api.example.com/updates" }
}
</pre>
<h4 style="margin-bottom: 45px; line-height: 1.3;">4.5.2 Normalise the key field for each stream</h4>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{
"name": "Set UID Users",
"type": "n8n-nodes-base.set",
"parameters": {
"values": {
"string": [{ "name": "uid", "value": "={{$json[\"id\"]}}" }]
}
}
}
</pre>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{
"name": "Set UID Updates",
"type": "n8n-nodes-base.set",
"parameters": {
"values": {
"string": [{ "name": "uid", "value": "={{$json[\"userId\"]}}" }]
}
}
}
</pre>
<h4 style="margin-bottom: 45px; line-height: 1.3;">4.5.3 Merge on the guaranteed‑unique <code>uid</code></h4>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{
"name": "Merge Users & Updates",
"type": "n8n-nodes-base.merge",
"parameters": {
"mode": "mergeBy",
"keyField": "uid",
"conflictHandling": "overwrite"
}
}
</pre>
<h4 style="margin-bottom: 45px; line-height: 1.3;">4.5.4 Connect the nodes (simplified)</h4>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">{
"connections": {
"HTTP Get Users": { "main": [[{ "node": "Set UID Users", "type": "main", "index": 0 }]] },
"HTTP Get Updates": { "main": [[{ "node": "Set UID Updates", "type": "main", "index": 0 }]] },
"Set UID Users": { "main": [[{ "node": "Merge Users & Updates", "type": "main", "index": 0 }]] },
"Set UID Updates": { "main": [[{ "node": "Merge Users & Updates", "type": "main", "index": 1 }]] }
}
}
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">Running this workflow merges the two streams on a <strong>guaranteed‑unique <code>uid</code></strong> and overwrites any accidental duplicates.</p>
<hr style="margin: 50px 0; border: none;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">5️⃣ Common conflict scenarios (quick reference)</h2>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="padding: 13px; border: 1px solid #ddd;">#</th>
<th style="padding: 13px; border: 1px solid #ddd;">Scenario</th>
<th style="padding: 13px; border: 1px solid #ddd;">Typical cause</th>
<th style="padding: 13px; border: 1px solid #ddd;">Recommended fix</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">1</td>
<td style="padding: 13px; border: 1px solid #ddd;">Duplicate <code>id</code> from two API calls</td>
<td style="padding: 13px; border: 1px solid #ddd;">Both APIs share the same primary‑key space</td>
<td style="padding: 13px; border: 1px solid #ddd;">Create a composite key (<code>apiName_id</code>).</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">2</td>
<td style="padding: 13px; border: 1px solid #ddd;">Missing key field in one input</td>
<td style="padding: 13px; border: 1px solid #ddd;">Field name typo or null value</td>
<td style="padding: 13px; border: 1px solid #ddd;">Add a <strong>Set</strong> node with a fallback: <code>{{ $json["id"] || $json["fallbackId"] }}</code>.</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">3</td>
<td style="padding: 13px; border: 1px solid #ddd;">Large batch + duplicate keys</td>
<td style="padding: 13px; border: 1px solid #ddd;">Batch > 10 k items triggers memory pressure</td>
<td style="padding: 13px; border: 1px solid #ddd;">Use <strong>SplitInBatches</strong> + <strong>Skip</strong> handling; log duplicates.</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">4</td>
<td style="padding: 13px; border: 1px solid #ddd;">Function node rewrites keys</td>
<td style="padding: 13px; border: 1px solid #ddd;">Custom mapping overwrites original keys</td>
<td style="padding: 13px; border: 1px solid #ddd;">Preserve original key in a new field (<code>originalId</code>) and merge on that.</td>
</tr>
</tbody>
</table>
<hr style="margin: 50px 0; border: none;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">6️⃣ Production‑grade EEFA recommendations</h2>
<ol style="margin-bottom: 2em; line-height: 1.9;">
<li><strong>Idempotency</strong> – Persist the generated unique key (DB, KV store) so repeated runs merge deterministically.</li>
<li><strong>Observability</strong> – Emit conflict metrics (total items, duplicates, overwritten) to a monitoring system (Grafana, Datadog).</li>
<li><strong>Rollback safety</strong> – When using <strong>Overwrite</strong>, snapshot the pre‑merge dataset to a temporary variable or external storage.</li>
<li><strong>Security</strong> – If the key contains PII (e.g., email), hash it before use: <code>{{ $json["email"] | md5 }}</code>.</li>
</ol>
<hr style="margin: 50px 0; border: none;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">7️⃣ Frequently asked questions</h2>
<h3 style="margin-bottom: 45px; line-height: 1.3;">Q: Can I merge more than two input streams?</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">A: Yes. Connect additional inputs to the same Merge node; they are processed sequentially with the same key/conflict settings.<br />
<strong>If you encounter any</strong> <a href="https://flowgenius.in/n8n-split-in-batches-node-limit-exceeded/">n8n split-in-batches node limit exceeded</a> <strong>resolve them before continuing with the setup.</strong></p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">Q: Does the Merge node preserve the order of items?</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">A: In <strong>Append</strong> mode, order is preserved. In <strong>Merge By</strong>, the order follows the first appearance of each unique key.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">Q: How do I debug a conflict without stopping the whole workflow?</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">A: Set <strong>Conflict handling</strong> to <strong>Skip</strong>, then add a <strong>Function</strong> node after the Merge to capture skipped items:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto;">return [{ json: { skipped: $node["Merge"].json.skipped } }];
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">Log or route this output for audit.</p>
<hr style="margin: 50px 0; border: none;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">Conclusion</h2>
<p style="margin-bottom: 2em; line-height: 1.9;">The Merge node’s conflict error is a safety net that fires when duplicate keys appear in <strong>Merge By</strong> mode. By ensuring a truly unique key (or a deterministic composite key), selecting the appropriate conflict‑handling strategy, and optionally batching large inputs, you can eliminate the error and keep your n8n pipelines reliable at scale. Apply the checklist, monitor conflicts in production, and you’ll have a robust, idempotent merge process that works across self‑hosted, Docker, and n8n.cloud deployments.</p>

Step by Step Guide to solve n8n Merge Node Conflict Error
Who this is for: n8n developers who use the Merge node to combine two or more data streams and need a reliable way to handle duplicate keys. We cover this in detail in the n8n Node Specific Errors Guide.
Quick Diagnosis
The “Merge node conflict error” appears when two input items share the same key field while the node is in “Merge By” mode and the Conflict handling option is set to “Throw error on conflict”.
Quick fix
- Open the Merge node → Mode = Merge By.
- Choose a Key Field that is guaranteed to be unique (e.g.,
id, uuid).
- If uniqueness cannot be guaranteed, change Conflict handling to “Overwrite” or “Skip”.
- (Optional) Add a Set node before the Merge to generate a unique composite key:
{{$json["id"]}}_{{$index}}.
Re‑run the workflow – the error disappears.
1️⃣ Why the Merge node throws a conflict error
If you encounter any n8n slack node rate limit resolve them before continuing with the setup.
| Situation |
Node behaviour |
Result |
| Two items share the same Key Field while Mode = Merge By |
The node tries to merge the items into a single record |
Default Conflict handling = Throw error → workflow stops |
| Mode = Append with duplicate items |
Items are simply concatenated |
No conflict check – duplicates remain |
| Mode = Keep Key with non‑unique keys |
First occurrence is kept, later ones ignored |
No error, but data may be silently dropped |
EEFA note: The error is intentional – it protects you from unintentionally overwriting data.
2️⃣ Merge node modes & conflict handling
| Mode |
What it does |
| Append |
Concatenates the two input arrays (no conflict check). |
| Merge By |
Merges items that share the same Key Field. |
| Keep Key |
Keeps the first occurrence of each key, discarding later ones. |
| Conflict handling (only for Merge By) |
Behaviour |
| Throw error (default) |
Stops execution on duplicate keys. |
| Overwrite |
Newer item replaces the older one. |
| Skip |
Keeps the first item, discards duplicates. |
Best practice: Use Overwrite only when you have a deterministic rule (e.g., latest timestamp). Otherwise prefer Skip and log the conflict. If you encounter any n8n google sheets node rate limit resolve them before continuing with the setup.
3️⃣ Pre‑run checklist (micro‑summary)
Before you execute the workflow, verify the following items to avoid conflicts.
- Key field is selected and truly unique across all inputs.
- Conflict handling matches your business rule (Overwrite / Skip).
- No null/undefined values in the key field (add a fallback if needed).
- Input batch size respects server limits – use SplitInBatches for large sets.
- Logging: capture skipped items for audit.
- [ ] Unique key field selected
- [ ] Conflict handling set appropriately
- [ ] No null keys (add fallback)
- [ ] Batch size within limits
- [ ] Skipped items logged
4️⃣ Step‑by‑step resolution guide
4.1 Identify the conflicting key
Add a Set node that copies the candidate key to a visible field (conflictKey).
{
"name": "Expose Key",
"type": "n8n-nodes-base.set",
"parameters": {
"values": {
"string": [
{
"name": "conflictKey",
"value": "={{$json[\"id\"]}}"
}
]
}
}
}
Run the workflow, open Execution → View Execution, and filter on conflictKey. Duplicate values are the culprits.
4.2 Ensure a truly unique key
Option A – Use an existing unique identifier (e.g., uuid).
Option B – Create a composite key with a Set node:
{{ $json["email"] + "_" + $json["createdAt"] }}
Reference this new field (compositeKey) in the Merge node’s Key Field.
4.3 Adjust conflict handling
Open the Merge node and select the appropriate option:
{
"mode": "mergeBy",
"keyField": "uid",
"conflictHandling": "skip" // or "overwrite"
}
- Skip – keeps the first occurrence, discards later duplicates.
- Overwrite – newer item replaces the older one (use with a deterministic rule).
4.4 (Optional) Split large batches before merging
When processing thousands of records, split the inputs to stay within memory limits:
{
"name": "Split Large Batch",
"type": "n8n-nodes-base.splitInBatches",
"parameters": { "batchSize": 500 }
}
Merge each batch individually, then concatenate the results with a Merge (Append) node.
4.5 Minimal working example (broken into bite‑size snippets)
4.5.1 Fetch two data streams
{
"name": "HTTP Get Users",
"type": "n8n-nodes-base.httpRequest",
"parameters": { "url": "https://api.example.com/users" }
}
{
"name": "HTTP Get Updates",
"type": "n8n-nodes-base.httpRequest",
"parameters": { "url": "https://api.example.com/updates" }
}
4.5.2 Normalise the key field for each stream
{
"name": "Set UID Users",
"type": "n8n-nodes-base.set",
"parameters": {
"values": {
"string": [{ "name": "uid", "value": "={{$json[\"id\"]}}" }]
}
}
}
{
"name": "Set UID Updates",
"type": "n8n-nodes-base.set",
"parameters": {
"values": {
"string": [{ "name": "uid", "value": "={{$json[\"userId\"]}}" }]
}
}
}
4.5.3 Merge on the guaranteed‑unique uid
{
"name": "Merge Users & Updates",
"type": "n8n-nodes-base.merge",
"parameters": {
"mode": "mergeBy",
"keyField": "uid",
"conflictHandling": "overwrite"
}
}
4.5.4 Connect the nodes (simplified)
{
"connections": {
"HTTP Get Users": { "main": [[{ "node": "Set UID Users", "type": "main", "index": 0 }]] },
"HTTP Get Updates": { "main": [[{ "node": "Set UID Updates", "type": "main", "index": 0 }]] },
"Set UID Users": { "main": [[{ "node": "Merge Users & Updates", "type": "main", "index": 0 }]] },
"Set UID Updates": { "main": [[{ "node": "Merge Users & Updates", "type": "main", "index": 1 }]] }
}
}
Running this workflow merges the two streams on a guaranteed‑unique uid and overwrites any accidental duplicates.
5️⃣ Common conflict scenarios (quick reference)
| # |
Scenario |
Typical cause |
Recommended fix |
| 1 |
Duplicate id from two API calls |
Both APIs share the same primary‑key space |
Create a composite key (apiName_id). |
| 2 |
Missing key field in one input |
Field name typo or null value |
Add a Set node with a fallback: {{ $json["id"] || $json["fallbackId"] }}. |
| 3 |
Large batch + duplicate keys |
Batch > 10 k items triggers memory pressure |
Use SplitInBatches + Skip handling; log duplicates. |
| 4 |
Function node rewrites keys |
Custom mapping overwrites original keys |
Preserve original key in a new field (originalId) and merge on that. |
6️⃣ Production‑grade EEFA recommendations
- Idempotency – Persist the generated unique key (DB, KV store) so repeated runs merge deterministically.
- Observability – Emit conflict metrics (total items, duplicates, overwritten) to a monitoring system (Grafana, Datadog).
- Rollback safety – When using Overwrite, snapshot the pre‑merge dataset to a temporary variable or external storage.
- Security – If the key contains PII (e.g., email), hash it before use:
{{ $json["email"] | md5 }}.
7️⃣ Frequently asked questions
Q: Can I merge more than two input streams?
A: Yes. Connect additional inputs to the same Merge node; they are processed sequentially with the same key/conflict settings.
If you encounter any n8n split-in-batches node limit exceeded resolve them before continuing with the setup.
Q: Does the Merge node preserve the order of items?
A: In Append mode, order is preserved. In Merge By, the order follows the first appearance of each unique key.
Q: How do I debug a conflict without stopping the whole workflow?
A: Set Conflict handling to Skip, then add a Function node after the Merge to capture skipped items:
return [{ json: { skipped: $node["Merge"].json.skipped } }];
Log or route this output for audit.
Conclusion
The Merge node’s conflict error is a safety net that fires when duplicate keys appear in Merge By mode. By ensuring a truly unique key (or a deterministic composite key), selecting the appropriate conflict‑handling strategy, and optionally batching large inputs, you can eliminate the error and keep your n8n pipelines reliable at scale. Apply the checklist, monitor conflicts in production, and you’ll have a robust, idempotent merge process that works across self‑hosted, Docker, and n8n.cloud deployments.