Understanding Merge Node Behaviour

Describe the issue/error/question

Recently discovered n8n and love it - kudos to the creators!

I seem to be having a hard time understanding how to use the Merge node in my workflows - it does not behave as I expect in multiple different scenarios. I will describe (hopefully) a simple one here to see if I can learn what I’m doing wrong.

What is the error message (if any)?

The node is in ‘passthrough’ mode, it receives both inputs, but outputs nothing and the workflow stops. Both of the previous IF nodes show data is output, and a single item sent to each input but the Merge mode itself shows ‘no text data found’.

Please share the workflow

{
  "nodes": [
    {
      "parameters": {
        "path": "633cf57f-4838-492b-9f60-526c3df307f6",
        "options": {}
      },
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        1120,
        1080
      ],
      "webhookId": "633cf57f-4838-492b-9f60-526c3df307f6"
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{$items()[0].json[\"Bind User\"]}}",
              "operation": "isEmpty"
            }
          ]
        }
      },
      "name": "IF User is NOT bound to an assignment1",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        1560,
        1160
      ]
    },
    {
      "parameters": {
        "operation": "incr",
        "key": "Semaphore",
        "expire": true,
        "ttl": 3
      },
      "name": "Redis1",
      "type": "n8n-nodes-base.redis",
      "typeVersion": 1,
      "position": [
        1400,
        980
      ],
      "credentials": {
        "redis": {
          "id": "3",
          "name": "Redis account"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "number": [
            {
              "value1": "={{$json[\"Semaphore\"]}}",
              "operation": "equal",
              "value2": 1
            }
          ]
        }
      },
      "name": "IF1",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        1560,
        980
      ]
    },
    {
      "parameters": {
        "mode": "passThrough",
        "output": "input2"
      },
      "name": "Merge1",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 1,
      "position": [
        2160,
        900
      ],
      "retryOnFail": false
    },
    {
      "parameters": {
        "amount": 3.1,
        "unit": "seconds"
      },
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1,
      "position": [
        1780,
        1220
      ],
      "webhookId": "3f1ba65a-13a3-4952-a417-67fee88efdef"
    },
    {
      "parameters": {
        "application": "appBx7nn0EMh5inEx",
        "table": "Asset Assignments",
        "id": "={{$items()[0].json[\"Assignment ID\"]}}"
      },
      "name": "Airtable1",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 1,
      "position": [
        1940,
        1220
      ],
      "credentials": {
        "airtableApi": {
          "id": "1",
          "name": "Airtable account"
        }
      }
    },
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "Bind User",
              "value": "={{$node[\"Webhook\"].json[\"query\"][\"userbinding\"]}}"
            },
            {
              "name": "Assignment ID",
              "value": "={{$node[\"Webhook\"].json[\"query\"][\"assignment\"]}}"
            }
          ]
        },
        "options": {}
      },
      "name": "Set2",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        1400,
        1160
      ]
    },
    {
      "parameters": {
        "amount": 3,
        "unit": "seconds"
      },
      "name": "Wait1",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1,
      "position": [
        1760,
        780
      ],
      "webhookId": "0095fd93-ea2c-44be-8c8b-07db2f58ea1a"
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "Bind User",
              "value": "={{$json[\"fields\"][\"Bind User to Assignment (from Assignee)\"][0]}}"
            },
            {
              "name": "Assignment ID",
              "value": "={{$json[\"id\"]}}"
            }
          ],
          "number": []
        },
        "options": {}
      },
      "name": "Set1",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        2100,
        1220
      ]
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Set2",
            "type": "main",
            "index": 0
          },
          {
            "node": "Redis1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF User is NOT bound to an assignment1": {
      "main": [
        [
          {
            "node": "Merge1",
            "type": "main",
            "index": 1
          }
        ],
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Redis1": {
      "main": [
        [
          {
            "node": "IF1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF1": {
      "main": [
        [
          {
            "node": "Merge1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait": {
      "main": [
        [
          {
            "node": "Airtable1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Airtable1": {
      "main": [
        [
          {
            "node": "Set1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set2": {
      "main": [
        [
          {
            "node": "IF User is NOT bound to an assignment1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait1": {
      "main": [
        [
          {
            "node": "Redis1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set1": {
      "main": [
        [
          {
            "node": "IF User is NOT bound to an assignment1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Share the output returned by the last node

Information on your n8n setup

Hi @Felix_is_stuck, I’m sorry to hear you’re having trouble. From looking at your workflow it seems to rely on a number of external data sources, so I am not entirely sure what’s happening yet.

In my test scenario the node was working as expected:

Could you share a dummy workflow not needing any additional data using which the problem can be reproduced?

1 Like

Welcome to the community @Felix_is_stuck and great to hear that you enjoy n8n!

Is it possible that the IF-Nodes (“IF1” or “IF User is NOT bound to an assignment”) never output any data on the true branch?

Thank you @MutedJam and @jan for your replies.

@jan, both IF nodes are outputting data.

To add a little more info, if the IF node “IF User is NOT bound to an assignment1” tests TRUE on the first pass, the merge node outputs as expected. Only when it fails on the first pass and then fetches new data from Airtable, does it fail when it next tests TRUE.

See the data Input 2 data below from both scenarios for comparison:

IF node “IF User is NOT bound to an assignment1” Output 1 (merge node operates as (I) expected:

[

{

“Bind User”: “”,

“Assignment ID”: “recmXMH99e5FVu0Pb”

}

]

IF node “IF User is NOT bound to an assignment1” Output 2 (merge node outputs nothing):

[

{

“Assignment ID”: “recmXMH99e5FVu0Pb”

}

]

IF node “IF1” outputs the same data each time it tests TRUE:

[

{

“Semaphore”: 1

}

]

I have another example here where the Merge node does not do as expected. I am using two Merge nodes in the Workflow, the first works flawlessly, the second however seems to trigger the node attached to input 2 prematurely (before this node has received any input) and as a result, it’s output doesn’t contain the data that I need.

Here is the flow:

{
  "nodes": [
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "Lat, Long",
              "value": "={{$json[\"body\"][\"Events\"][0][\"point\"][\"latitude\"]}},{{$json[\"body\"][\"Events\"][0][\"point\"][\"longitude\"]}}"
            },
            {
              "name": "message",
              "value": "={{$json[\"body\"][\"Events\"][0][\"freeText\"]}}"
            },
            {
              "name": "messageCode",
              "value": "={{$json[\"body\"][\"Events\"][0][\"messageCode\"]}}"
            },
            {
              "name": "IMEI",
              "value": "={{$json[\"body\"][\"Events\"][0][\"imei\"]}}"
            }
          ],
          "number": [
            {
              "name": "Timestamp",
              "value": "={{$json[\"body\"][\"Events\"][0][\"timeStamp\"]}}"
            },
            {
              "name": "Altitude",
              "value": "={{$json[\"body\"][\"Events\"][0][\"point\"][\"altitude\"]}}"
            },
            {
              "name": "Course",
              "value": "={{$json[\"body\"][\"Events\"][0][\"point\"][\"course\"]}}"
            },
            {
              "name": "Speed",
              "value": "={{$json[\"body\"][\"Events\"][0][\"point\"][\"speed\"]}}"
            }
          ]
        },
        "options": {}
      },
      "name": "Set - Garmin API Variables",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        -4360,
        1780
      ]
    },
    {
      "parameters": {
        "operation": "list",
        "application": "appBx7nn0EMh5inEx",
        "table": "Assets",
        "additionalOptions": {
          "filterByFormula": "={IMEI}='{{$json[\"IMEI\"]}}'"
        }
      },
      "name": "Lookup User from Assets",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 1,
      "position": [
        -4140,
        2000
      ],
      "alwaysOutputData": true,
      "credentials": {
        "airtableApi": {
          "id": "1",
          "name": "Airtable account"
        }
      }
    },
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "IMEI",
              "value": "={{$node[\"Set - Garmin API Variables\"].json[\"IMEI\"]}}"
            },
            {
              "name": "senderName",
              "value": "={{ $json[\"fields\"][\"Name\"] ? $json[\"fields\"][\"Name\"] : \"Unassigned\" }}"
            }
          ]
        },
        "options": {}
      },
      "name": "Set senderName",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        -3380,
        2000
      ]
    },
    {
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{$json[\"fields\"][\"Assigned to\"] ? true : false }}",
              "value2": true
            }
          ]
        }
      },
      "name": "IF",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        -3960,
        2000
      ]
    },
    {
      "parameters": {
        "application": "appBx7nn0EMh5inEx",
        "table": "Users",
        "id": "={{$json[\"fields\"][\"Assigned to\"][0]}}"
      },
      "name": "Lookup User Name",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 1,
      "position": [
        -3560,
        1880
      ],
      "credentials": {
        "airtableApi": {
          "id": "1",
          "name": "Airtable account"
        }
      }
    },
    {
      "parameters": {
        "operation": "get",
        "propertyName": "ActiveBaseID",
        "key": "newBaseRecordId",
        "keyType": "string",
        "options": {}
      },
      "name": "Get ActiveBaseID2",
      "type": "n8n-nodes-base.redis",
      "typeVersion": 1,
      "position": [
        -4580,
        2120
      ],
      "credentials": {
        "redis": {
          "id": "3",
          "name": "Redis account"
        }
      }
    },
    {
      "parameters": {
        "value": "={{$json[\"body\"][\"Events\"][0][\"timeStamp\"]}}",
        "dataPropertyName": "dateTime",
        "custom": true,
        "toFormat": "MM/DD/YYYY HH:mm",
        "options": {
          "fromFormat": "x"
        }
      },
      "name": "Date & Time",
      "type": "n8n-nodes-base.dateTime",
      "typeVersion": 1,
      "position": [
        -4520,
        1920
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "62c4984a-9636-40f5-95f0-ed7c279677b4",
        "options": {}
      },
      "name": "Garmin IPC Inbound Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        -4800,
        1780
      ],
      "webhookId": "2a41df13-5565-459d-8753-9ba76b6caf2c"
    },
    {
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{$node[\"Garmin IPC Inbound Webhook\"].json[\"body\"][\"Events\"][0][\"point\"][\"latitude\"] !== 0 && $node[\"Garmin IPC Inbound Webhook\"].json[\"body\"][\"Events\"][0][\"point\"][\"longitude\"] !== 0 ? true : false }}",
              "value2": true
            }
          ]
        }
      },
      "name": "IF payload contains Lat Long",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        -4180,
        2220
      ]
    },
    {
      "parameters": {
        "url": "https://maps.googleapis.com/maps/api/geocode/json",
        "options": {},
        "queryParametersUi": {
          "parameter": [
            {
              "name": "key",
              "value": "XXXX"
            },
            {
              "name": "latlng",
              "value": "={{$json[\"Lat, Long\"]}}"
            },
            {
              "name": "language",
              "value": "en"
            }
          ]
        }
      },
      "name": "HTTP Get Place ID",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        -3860,
        2340
      ]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{$json[\"status\"]}}",
              "value2": "OK"
            }
          ]
        }
      },
      "name": "IF Status OK1",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        -3660,
        2340
      ]
    },
    {
      "parameters": {
        "url": "=https://maps.googleapis.com/maps/api/place/details/json",
        "options": {},
        "queryParametersUi": {
          "parameter": [
            {
              "name": "key",
              "value": "XXXX"
            },
            {
              "name": "place_id",
              "value": "={{$json[\"candidates\"][0][\"place_id\"] ? $json[\"candidates\"][0][\"place_id\"] : ''}}{{$json[\"results\"][0][\"place_id\"] ? $json[\"results\"][0][\"place_id\"] : ''}}"
            },
            {
              "name": "language",
              "value": "en"
            }
          ]
        }
      },
      "name": "HTTP Get Place Details",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        -3440,
        2220
      ]
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "results",
              "value": "={{[$json[\"result\"]]}}"
            },
            {
              "name": "Lat, Long",
              "value": "={{$node[\"Set - Garmin API Variables\"].json[\"Lat, Long\"]}}"
            }
          ]
        },
        "options": {}
      },
      "name": "Set Results Array1",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        -3260,
        2220
      ]
    },
    {
      "parameters": {
        "functionCode": "if (typeof item.result.address_components.find(e => e.types.includes(\"street_number\")) !== 'undefined') {\n    item[\"street_number\"] = item.result.address_components.find(e => e.types.includes(\"street_number\")).long_name;\n}\n\nif (typeof item.result.address_components.find(e => e.types.includes(\"route\")) !== 'undefined') {\n    item[\"route\"] = item.result.address_components.find(e => e.types.includes(\"route\")).long_name;\n}\n\nif (typeof item.result.address_components.find(e => e.types.includes(\"locality\")) !== 'undefined') {\n    item[\"locality\"] = item.result.address_components.find(e => e.types.includes(\"locality\")).long_name;\n}\n\nif (typeof item.result.address_components.find(e => e.types.includes(\"postal_town\")) !== 'undefined') {\n    item[\"postal_town\"] = item.result.address_components.find(e => e.types.includes(\"postal_town\")).long_name;\n}\n\nif (typeof item.result.address_components.find(e => e.types.includes(\"administrative_area_level_1\")) !== 'undefined') {\n    item[\"administrative_area_level_1\"] = item.result.address_components.find(e => e.types.includes(\"administrative_area_level_1\")).long_name;\n}\n\nif (typeof item.result.address_components.find(e => e.types.includes(\"administrative_area_level_2\")) !== 'undefined') {\n    item[\"administrative_area_level_2\"] = item.result.address_components.find(e => e.types.includes(\"administrative_area_level_2\")).long_name;\n}\n\nif (typeof item.result.address_components.find(e => e.types.includes(\"administrative_area_level_3\")) !== 'undefined') {\n    item[\"administrative_area_level_3\"] = item.result.address_components.find(e => e.types.includes(\"administrative_area_level_3\")).long_name;\n}\n\nif (typeof item.result.address_components.find(e => e.types.includes(\"political\")) !== 'undefined') {\n    item[\"political\"] = item.result.address_components.find(e => e.types.includes(\"political\")).long_name;\n}\n\nif (typeof item.result.address_components.find(e => e.types.includes(\"postal_code\")) !== 'undefined') {\n    item[\"postal_code\"] = item.result.address_components.find(e => e.types.includes(\"postal_code\")).long_name;\n}\n\nif (typeof item.result.address_components.find(e => e.types.includes(\"country\")) !== 'undefined') {\n    item[\"country\"] = item.result.address_components.find(e => e.types.includes(\"country\")).long_name;\n}\n\nreturn item;\n"
      },
      "name": "FunctionItem. - Parse Address Components",
      "type": "n8n-nodes-base.functionItem",
      "typeVersion": 1,
      "position": [
        -3080,
        2220
      ]
    },
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "Lat Long",
              "value": "={{$node[\"Set - Garmin API Variables\"].json[\"Lat, Long\"] ? $node[\"Set - Garmin API Variables\"].json[\"Lat, Long\"] : ''}}"
            },
            {
              "name": "Formatted Address",
              "value": "={{$node[\"HTTP Get Place ID\"].json[\"status\"] == 'OK' ? $json[\"result\"][\"formatted_address\"] : 'Not found: location set with Lat, Long coordinates only'}}"
            },
            {
              "name": "Place ID",
              "value": "={{$node[\"HTTP Get Place ID\"].json[\"status\"] == 'ok' ? $json[\"result\"][\"place_id\"] : ''}}"
            },
            {
              "name": "Address",
              "value": "={{$json[\"street_number\"] ? $json[\"street_number\"]+' ' : ''}}{{$json[\"route\"] ? $json[\"route\"] : ''}}"
            },
            {
              "name": "City",
              "value": "={{$json[\"locality\"] ? $json[\"locality\"] : $json[\"postal_town\"] ? $json[\"postal_town\"] : ''}}"
            },
            {
              "name": "State",
              "value": "={{$json[\"administrative_area_level_1\"] ? $json[\"administrative_area_level_1\"] : ''}}"
            },
            {
              "name": "Zip",
              "value": "={{$json[\"postal_code\"] ? $json[\"postal_code\"] : ''}}"
            },
            {
              "name": "Country",
              "value": "={{$json[\"country\"] ? $json[\"country\"] : ''}}"
            },
            {
              "name": "IMEI",
              "value": "={{ $node[\"Set - Garmin API Variables\"].json[\"IMEI\"] }}"
            }
          ],
          "number": []
        },
        "options": {}
      },
      "name": "Set Location Values",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        -2820,
        2000
      ]
    },
    {
      "parameters": {
        "mode": "mergeByKey",
        "propertyName1": "IMEI",
        "propertyName2": "IMEI",
        "overwrite": "undefined"
      },
      "name": "Merge - Add Sender",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 1,
      "position": [
        -3280,
        1800
      ]
    },
    {
      "parameters": {
        "mode": "mergeByKey",
        "propertyName1": "IMEI",
        "propertyName2": "IMEI",
        "overwrite": "undefined"
      },
      "name": "Merge - Add Location Data",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 1,
      "position": [
        -2340,
        1820
      ]
    },
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "fields.Name",
              "value": "Unassigned"
            }
          ]
        },
        "options": {}
      },
      "name": "Set2",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        -3740,
        2100
      ]
    }
  ],
  "connections": {
    "Set - Garmin API Variables": {
      "main": [
        [
          {
            "node": "Lookup User from Assets",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge - Add Sender",
            "type": "main",
            "index": 0
          },
          {
            "node": "IF payload contains Lat Long",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lookup User from Assets": {
      "main": [
        [
          {
            "node": "IF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set senderName": {
      "main": [
        [
          {
            "node": "Merge - Add Sender",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "IF": {
      "main": [
        [
          {
            "node": "Lookup User Name",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lookup User Name": {
      "main": [
        [
          {
            "node": "Set senderName",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Garmin IPC Inbound Webhook": {
      "main": [
        [
          {
            "node": "Get ActiveBaseID2",
            "type": "main",
            "index": 0
          },
          {
            "node": "Set - Garmin API Variables",
            "type": "main",
            "index": 0
          },
          {
            "node": "Date & Time",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF payload contains Lat Long": {
      "main": [
        [
          {
            "node": "HTTP Get Place ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Get Place ID": {
      "main": [
        [
          {
            "node": "IF Status OK1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Status OK1": {
      "main": [
        [
          {
            "node": "HTTP Get Place Details",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set Location Values",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Get Place Details": {
      "main": [
        [
          {
            "node": "Set Results Array1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Results Array1": {
      "main": [
        [
          {
            "node": "FunctionItem. - Parse Address Components",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "FunctionItem. - Parse Address Components": {
      "main": [
        [
          {
            "node": "Set Location Values",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Location Values": {
      "main": [
        [
          {
            "node": "Merge - Add Location Data",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge - Add Sender": {
      "main": [
        [
          {
            "node": "Merge - Add Location Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set2": {
      "main": [
        [
          {
            "node": "Set senderName",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Those are two different things. The 2 on the node means it got executed twice (as you did connect two nodes and each connection executes the node 1x), the 2 on the connection means that both executions combined have 2 items (so in this case 1 item each).

The Merge node combines data of the one execution of input 1, with the data of one execution of input 2. For the second execution there is never any data on input 1 and for that reason does it get ignored (or lost). What you probably want to do is not have a Set-Node with two input connections (and so different runs) you want to combine the data first with a Merge-Node that they end up in the same execution.

1 Like

Hi @jan! Thanks for your reply.

I still don’t get it.

You say “(as you did connect two nodes and each connection executes the node 1x)” - the two connectors to my Set node are the opposing paths from a previous IF node (see additional screenshot below):

Why would the FALSE path on the IF node trigger the Set node? I does not generally behave in this fashion - I only see it now when using the Merge node.

Can you please share a screenshot of the full workflow? Sounds like it is potentially the same issue as described here: Switch and merge node