Link-out link-in in subflows, after copy

I have a template to connect my device inside, it uses link-out link-in nodes, when I cloned it using export/import I lost all link connections inside, same if I try to copy/paste linked nodes to other subflow, is it something with my setup, or node-red does not recalculate link ids on copy/paste and export ? It makes link usage very limited and make me think to refactor all back to wires.

Please can you give an example to debug it.

Yes, one second, just found that it was bug already Export/import links disconnected in subflows Ā· Issue #4055 Ā· node-red/node-red Ā· GitHub

so collecting info, my node is

version: 3.1.9

That issue is closed as "fixed" see comment: Export/import links disconnected in subflows Ā· Issue #4055 Ā· node-red/node-red Ā· GitHub

So either there is a regression or is a different problem.
Can you confirm the steps in that issue are exactly the same as you are seeing in v3.1.9?

so reproduced it, follow this simple steps to repeat:

  • import provided code
  • in Subflow1 there is function and another subflow - export it, and import with view-nodes... copy checkboxed to the same Subflow1
  • check copy and original - in my case they disconnected
code
[
    {
        "id": "671fd229d55cc4d1",
        "type": "subflow",
        "name": "have links inside",
        "info": "",
        "category": "",
        "in": [
            {
                "x": 80,
                "y": 100,
                "wires": [
                    {
                        "id": "a39dc90d7144616f"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 640,
                "y": 100,
                "wires": [
                    {
                        "id": "29c751aab0f9300f",
                        "port": 0
                    }
                ]
            },
            {
                "x": 640,
                "y": 240,
                "wires": [
                    {
                        "id": "47ce190f78c786b2",
                        "port": 0
                    }
                ]
            }
        ],
        "env": [],
        "meta": {},
        "color": "#DDAA99"
    },
    {
        "id": "e8309cbccae18876",
        "type": "function",
        "z": "671fd229d55cc4d1",
        "g": "3d47e1b41cda7dc4",
        "name": "doing something",
        "func": "\nreturn [msg];",
        "outputs": 2,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 380,
        "y": 140,
        "wires": [
            [
                "e3d3966e1fd317f1"
            ],
            [
                "dbcb9707ca5d578d"
            ]
        ]
    },
    {
        "id": "49b8775d8a0e2462",
        "type": "link in",
        "z": "671fd229d55cc4d1",
        "g": "3d47e1b41cda7dc4",
        "name": "link in 1",
        "links": [
            "a39dc90d7144616f"
        ],
        "x": 225,
        "y": 140,
        "wires": [
            [
                "e8309cbccae18876"
            ]
        ]
    },
    {
        "id": "a39dc90d7144616f",
        "type": "link out",
        "z": "671fd229d55cc4d1",
        "name": "link out 1",
        "mode": "link",
        "links": [
            "49b8775d8a0e2462"
        ],
        "x": 145,
        "y": 100,
        "wires": []
    },
    {
        "id": "e3d3966e1fd317f1",
        "type": "link out",
        "z": "671fd229d55cc4d1",
        "g": "3d47e1b41cda7dc4",
        "name": "link out 2",
        "mode": "link",
        "links": [
            "29c751aab0f9300f"
        ],
        "x": 495,
        "y": 120,
        "wires": [],
        "icon": "font-awesome/fa-thumbs-up"
    },
    {
        "id": "29c751aab0f9300f",
        "type": "link in",
        "z": "671fd229d55cc4d1",
        "name": "link in 2",
        "links": [
            "e3d3966e1fd317f1"
        ],
        "x": 575,
        "y": 100,
        "wires": [
            []
        ],
        "icon": "font-awesome/fa-thumbs-up"
    },
    {
        "id": "dbcb9707ca5d578d",
        "type": "link out",
        "z": "671fd229d55cc4d1",
        "g": "3d47e1b41cda7dc4",
        "name": "link out 3",
        "mode": "link",
        "links": [
            "47ce190f78c786b2"
        ],
        "x": 495,
        "y": 160,
        "wires": []
    },
    {
        "id": "47ce190f78c786b2",
        "type": "link in",
        "z": "671fd229d55cc4d1",
        "name": "link in 3",
        "links": [
            "dbcb9707ca5d578d"
        ],
        "x": 585,
        "y": 240,
        "wires": [
            []
        ]
    },
    {
        "id": "3d47e1b41cda7dc4",
        "type": "group",
        "z": "671fd229d55cc4d1",
        "style": {
            "stroke": "#999999",
            "stroke-opacity": "1",
            "fill": "none",
            "fill-opacity": "1",
            "label": true,
            "label-position": "nw",
            "color": "#a4a4a4"
        },
        "nodes": [
            "e8309cbccae18876",
            "49b8775d8a0e2462",
            "e3d3966e1fd317f1",
            "dbcb9707ca5d578d"
        ],
        "x": 184,
        "y": 79,
        "w": 352,
        "h": 122
    },
    {
        "id": "2ba1654070afcce1",
        "type": "subflow",
        "name": "Subflow 1",
        "info": "",
        "in": [],
        "out": []
    },
    {
        "id": "59950c9dfd1e8cb5",
        "type": "function",
        "z": "2ba1654070afcce1",
        "name": "function 2",
        "func": "\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 240,
        "y": 100,
        "wires": [
            []
        ]
    },
    {
        "id": "18c2d4fa0a5a3f2a",
        "type": "subflow:671fd229d55cc4d1",
        "z": "2ba1654070afcce1",
        "name": "",
        "x": 260,
        "y": 200,
        "wires": [
            [],
            []
        ]
    },
    {
        "id": "f7e36cb09e5e6b5b",
        "type": "subflow:2ba1654070afcce1",
        "z": "3c4154b39eca0635",
        "name": "",
        "x": 500,
        "y": 860,
        "wires": []
    }
]
screenshots

image
image

image
image

upd, same will happen if you copy all from subflow with links and paste it to any other subflow (not top flow)

I confirm, I know why - will add the reason to the issue

1 Like

while reproducing, I think I found workaround - to clone to top flow and then just copy inside subflow as initialised node ?

upd: another issue with import - can't import subflow to itself, even if importing copy, I think it is not fair :slight_smile: while may be not much use case.

That would give you an infinite set of subflows inside each other, as each one would include another copy inside.

I mean, if I mark to clone all I copy, it shall just copy, there shall be no infinity, because it I clone parent too, and Import it from hardcopy of "exported json"... there shall be no real link between what I paste and where I paste.

Sorry, I have no idea what you mean. Please explain exactly what you are unable to do.

1 Like

Sorry, I can't give you a solution.

But to let you know:

I have had this problem myself - a LONG TIME AGO!

Alas I am not able to remember how I fixed it.

Could you tell us the version of NR you are running?

@Colin I already explained, but ok, screenshots for you.

screens

image
image


image

Next step, I making full copy of Subflow2, so assume it shall be important without problems.

screens

image
image

I assume it wrong behavior, because if I import to top flow 1st and copy result subflow to "itself", I not getting any errors and expect exactly same if I import being inside subflow. It is not critical, but points to some mess in order of node creation and register inside subflow. May be above patch will fix this because it seems related.

Uh, you want to copy a subflow inside the subflow?

No, I not want copy, just found this while repeating bug with import links, I think it just unexpected, that it have error at this moment, because logically - things I importing are not part of current flow, just having similar ids.

It can became inconvinience in some rare cases, like if you had a template function and importing it to several places, finally it can happen that you import "template" to subflow which was source of such template (or first instance). I bet one who get this will think a lot "why complete different function is "itself" ?"

Mmm, can you please give us a list of steps to follow to see the problem.

Because the second image is misleading.

In second image I just click "edit subflow" for Subflow2, after exporting it. Not sure what missleading. Subflow itself is just dummy "create subflow" from "function" nothing inside

But why? Where (flow/subflow tab) you have imported the subflow?

Yes, Inside the subflow, sorry for misscommunication (I not want to copy subflow inside itself, but I tried)

This is result I expect to receive when doing so

flow
[
    {
        "id": "ba2c0867ebceaeac",
        "type": "subflow",
        "name": "Subflow 2",
        "info": "",
        "in": [],
        "out": []
    },
    {
        "id": "ce10381db1559d8d",
        "type": "function",
        "z": "ba2c0867ebceaeac",
        "name": "function 3",
        "func": "\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 200,
        "y": 80,
        "wires": [
            []
        ]
    },
    {
        "id": "4875d2d320e854a1",
        "type": "subflow",
        "name": "Subflow 2",
        "info": "",
        "in": [],
        "out": []
    },
    {
        "id": "3c6908f4a035f01f",
        "type": "function",
        "z": "4875d2d320e854a1",
        "name": "function 3",
        "func": "\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 200,
        "y": 80,
        "wires": [
            []
        ]
    },
    {
        "id": "9ed73a9016d9b75c",
        "type": "subflow:ba2c0867ebceaeac",
        "z": "4875d2d320e854a1",
        "name": "",
        "x": 260,
        "y": 180,
        "wires": []
    },
    {
        "id": "99aedb3212b835d3",
        "type": "subflow:4875d2d320e854a1",
        "z": "3c4154b39eca0635",
        "name": "",
        "x": 360,
        "y": 980,
        "wires": []
    }
]

I acheived above same way as link import workaround - Import it to top flow and than copy with copy/paste inside.

Strange here that I can't import just inside Subflow2 , because result is same and no "infinite repeating" happen, so I think it checks not nodes it going to insert, but original nodes user pasted.

For the loop part, I don't know how to explain it to you - maybe @knolleary or @dceejay if he's available.

When you import a subflow node into a subflow, the import will fail because the active workspace (the tab) is your subflow.