Skip to content

⛓️‍💥🐛 Item linking breaks in Execute Sub-workflow node #14568

Description

@pemontto

Bug Description

Item linking can break when calling sub workflows with mode Run once with all items. This is non-obvious and silently fails.

It seems the execute workflow node naively returns the pairedItems from the last node in the sub-workflow, which doesn't get resolved to the triggered input. This means item linking will break if you sub workflow:

  1. changes the order of items
  2. filters some items

Effectively the parent workflow can trace the pairedItem path through the child workflow, so takes the returned pairedItems at face value 😢

To Reproduce

  • Create a parent workflow with a list of 6 post IDs in Create Data Image
Parent workflow JSON
{
  "nodes": [
    {
      "parameters": {
        "jsCode": "return [\n  {json: {_postId: 1}},\n  {json: {_postId: 2}},\n  {json: {_postId: 3}},\n  {json: {_postId: 4}},\n  {json: {_postId: 5}},\n  {json: {_postId: 6}}\n]"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        0,
        -240
      ],
      "id": "4cf01608-f335-4099-abf4-30ecf318a667",
      "name": "Create Data"
    },
    {
      "parameters": {
        "workflowId": {
          "__rl": true,
          "value": "pkIgVSKKNMBYfgPq",
          "mode": "list",
          "cachedResultName": "Drop Some Stuff Sub Workflow"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {},
          "matchingColumns": [],
          "schema": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        },
        "options": {}
      },
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.2,
      "position": [
        220,
        -240
      ],
      "id": "19c76c59-91b4-4611-8d46-30c0c61696d0",
      "name": "Execute Workflow"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "20671d7e-9415-495f-add3-172eae1a5a69",
              "name": "Linked Parent Workflow _postId",
              "value": "={{ $('Create Data').item.json._postId }}",
              "type": "number"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        440,
        -240
      ],
      "id": "1fe800f1-96bf-4161-8a82-2aa061efb32c",
      "name": "Join to Original"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -220,
        -240
      ],
      "id": "a4d52565-c699-4daf-a2e1-5c176fe3e25c",
      "name": "When clicking ‘Test workflow’"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        880,
        -340
      ],
      "id": "324fef88-e2d8-4838-9cc8-a04fc37b832b",
      "name": "Good"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        880,
        -140
      ],
      "id": "5a20201a-b420-49c5-b5c2-c86736fdeeb1",
      "name": "Quite Bad"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "0f96d0b0-d646-4199-81e7-31568b4e94de",
              "leftValue": "={{ $json._postId }}",
              "rightValue": "={{ $json['Linked Parent Workflow _postId'] }}",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "looseTypeValidation": true,
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        660,
        -240
      ],
      "id": "09e26d12-d170-4b77-ab17-ff0e08dc0778",
      "name": "Correct"
    }
  ],
  "connections": {
    "Create Data": {
      "main": [
        [
          {
            "node": "Execute Workflow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Workflow": {
      "main": [
        [
          {
            "node": "Join to Original",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Join to Original": {
      "main": [
        [
          {
            "node": "Correct",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking ‘Test workflow’": {
      "main": [
        [
          {
            "node": "Create Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Correct": {
      "main": [
        [
          {
            "node": "Good",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Quite Bad",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {}
}
  • Create a sub workflow that filters and/or reorders items Image
Sub workflow JSON
{
  "nodes": [
    {
      "parameters": {
        "url": "=https://jsonplaceholder.typicode.com/posts/{{ $json._postId || $position + 1 }}",
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      },
      "id": "d0cc51c2-2d85-494e-86f2-5b1e90b389e4",
      "name": "Get Post",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -240,
        40
      ]
    },
    {
      "parameters": {
        "url": "=https://jsonplaceholder.typicode.com/users/{{ $json.userId }}",
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      },
      "id": "5e88592e-872a-4744-bdab-639d9abf39a2",
      "name": "Get Author",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        200,
        40
      ]
    },
    {
      "parameters": {
        "jsCode": "for (let index = 0; index < $input.all().length; index++) {\n  const item = $input.all()[index];\n  const item1 = $('Trigger').itemMatching(index);\n  item.json['Current pairedItem'] = item.pairedItem.item;\n  item.json['Trigger pairedItem'] = item1.pairedItem.item;\n  // Replace the pairedItems with items linked from the trigger\n  item.pairedItem = item1.pairedItem;\n}\n\nreturn $input.all();"
      },
      "id": "a0856b64-b7ff-48a8-a0e1-73724f7d914d",
      "name": "FIX",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        760,
        -160
      ]
    },
    {
      "parameters": {},
      "id": "6ff5c77b-ae61-43e5-af90-f9b6ff6022b3",
      "name": "Trigger",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1,
      "position": [
        -500,
        -100
      ]
    },
    {
      "parameters": {
        "content": "### Connect this to fix when called by a parent workflow 🛠️",
        "height": 260,
        "width": 280,
        "color": 3
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        680,
        -240
      ],
      "typeVersion": 1,
      "id": "3b415ade-6884-42f1-b6c1-935f5b42e9a5",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 1
          },
          "conditions": [
            {
              "id": "caafc48c-f911-49c4-993d-697590157a41",
              "leftValue": "={{ $json.id % 2 }}",
              "rightValue": 1,
              "operator": {
                "type": "number",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {
          "looseTypeValidation": true
        }
      },
      "id": "37ab24c9-2eeb-431c-8222-668868f57980",
      "name": "Odd",
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2,
      "position": [
        -40,
        40
      ]
    },
    {
      "parameters": {
        "type": "random"
      },
      "type": "n8n-nodes-base.sort",
      "typeVersion": 1,
      "position": [
        -40,
        -260
      ],
      "id": "66b91bdf-3f03-4440-9a67-779e78036371",
      "name": "Sort"
    },
    {
      "parameters": {
        "type": "random"
      },
      "type": "n8n-nodes-base.sort",
      "typeVersion": 1,
      "position": [
        200,
        -260
      ],
      "id": "5dbb6c63-f5c1-4860-a57f-8206f5feff52",
      "name": "Sort1"
    },
    {
      "parameters": {
        "content": "## End here OK ✅",
        "height": 200,
        "width": 220
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -100,
        -320
      ],
      "typeVersion": 1,
      "id": "2a8c26ee-d1b3-488a-b06a-231bcca5c9cb",
      "name": "Sticky Note2"
    },
    {
      "parameters": {
        "content": "## End here Bad ❌",
        "height": 200,
        "width": 220
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        140,
        -320
      ],
      "typeVersion": 1,
      "id": "ee11d6c1-c145-41e8-99d7-654615e6f6a5",
      "name": "Sticky Note3"
    },
    {
      "parameters": {
        "content": "## End here OK ✅",
        "height": 200,
        "width": 220
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -100,
        -20
      ],
      "typeVersion": 1,
      "id": "5bfc34df-b51a-433b-b792-28541a99329f",
      "name": "Sticky Note4"
    },
    {
      "parameters": {
        "content": "## End here Bad ❌",
        "height": 200,
        "width": 400
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        140,
        -20
      ],
      "typeVersion": 1,
      "id": "540d91b7-83ff-4298-8547-1cbb9efd3d7a",
      "name": "Sticky Note5"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "206bba29-9c20-4a7b-98b6-df12aa5a9bfa",
              "name": "_postId",
              "value": "={{ $('Trigger').item.json._postId }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "221ad5aa-a085-4928-8ce1-e4d6b9d5e27b",
      "name": "Set _postId",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        380,
        40
      ]
    },
    {
      "parameters": {
        "content": "## Reordering Example",
        "height": 300,
        "width": 880,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -320,
        -380
      ],
      "typeVersion": 1,
      "id": "74ab67e0-7e1c-4bec-b011-61af04917af2",
      "name": "Sticky Note1"
    },
    {
      "parameters": {
        "content": "## Filtering Example",
        "height": 300,
        "width": 880,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -320,
        -60
      ],
      "typeVersion": 1,
      "id": "761a7df5-1bbd-47e4-b55c-02f8b1208262",
      "name": "Sticky Note6"
    }
  ],
  "connections": {
    "Get Post": {
      "main": [
        [
          {
            "node": "Odd",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Author": {
      "main": [
        [
          {
            "node": "Set _postId",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Trigger": {
      "main": [
        [
          {
            "node": "Sort",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Odd": {
      "main": [
        [
          {
            "node": "Get Author",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sort": {
      "main": [
        [
          {
            "node": "Sort1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sort1": {
      "main": [
        []
      ]
    },
    "Set _postId": {
      "main": [
        []
      ]
    }
  },
  "pinData": {
    "Trigger": [
      {
        "_postId": 1
      }
    ]
  }
}
  • Update the execute workflow node in the parent to point at your sub workflow
  • Try running the sub workflow with with either example, and observe the item linking break when a subsequent node in the child workflow wipes out the pairedItems from the trigger
  • Notice how connecting the FIX node to either corrects the output in the parent node
for (let index = 0; index < $input.all().length; index++) {
  const item = $input.all()[index];
  const item1 = $('Trigger').itemMatching(index);
  item.json['Current pairedItem'] = item.pairedItem.item;
  item.json['Trigger pairedItem'] = item1.pairedItem.item;
  // Replace the pairedItems with items linked from the trigger
  item.pairedItem = item1.pairedItem;
}

return $input.all();

Expected behavior

  1. The execute workflow node should be pairedItem aware and update the item linking to point to the correct items
  2. This should be documented, it's a silent failure condition that can really mess up workflows

Operating System

Alpine Linux

n8n Version

1.86.1

Node.js Version

20.19.0

Database

SQLite (default)

Execution mode

main (default)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions