"No response object" after split/join

I'm trying my first steps with Node-RED.
I would like to use the split and join nodes in an HTTP flow, but the res property gets lost on join, so my flow fails with the HTTP response node complaining about "no response object".

A simplified example, consisting of four nodes (HTTP In, Split, Join, HTTP Response), using the "reduce sequence" example from the documentation to calculate the average of an array of numbers:

[
    {
        "id": "9e5f48c16729e4f0",
        "type": "tab",
        "label": "Flow 2",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "f4209033d0b98ad1",
        "type": "join",
        "z": "9e5f48c16729e4f0",
        "name": "",
        "mode": "reduce",
        "build": "object",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": "\\n",
        "joinerType": "str",
        "accumulate": true,
        "timeout": "",
        "count": "",
        "reduceRight": false,
        "reduceExp": "$A+payload",
        "reduceInit": "0",
        "reduceInitType": "num",
        "reduceFixup": "$A/$N",
        "x": 530,
        "y": 200,
        "wires": [
            [
                "40982d7b37a20db2"
            ]
        ]
    },
    {
        "id": "40982d7b37a20db2",
        "type": "http response",
        "z": "9e5f48c16729e4f0",
        "name": "",
        "statusCode": "",
        "headers": {},
        "x": 750,
        "y": 200,
        "wires": []
    },
    {
        "id": "d7649e2faf944cea",
        "type": "split",
        "z": "9e5f48c16729e4f0",
        "name": "",
        "splt": "\\n",
        "spltType": "str",
        "arraySplt": 1,
        "arraySpltType": "len",
        "stream": false,
        "addname": "",
        "x": 330,
        "y": 200,
        "wires": [
            [
                "f4209033d0b98ad1"
            ]
        ]
    },
    {
        "id": "de29676d03629e55",
        "type": "http in",
        "z": "9e5f48c16729e4f0",
        "name": "",
        "url": "/avg",
        "method": "post",
        "upload": false,
        "swaggerDoc": "",
        "x": 120,
        "y": 200,
        "wires": [
            [
                "d7649e2faf944cea"
            ]
        ]
    }
]

When invoking this with

curl -d "[2,3,4]" -H "Content-Type: application/json" "http://localhost:1880/avg"

I would expect to get "3" as response. Instead, the flow fails with "no response object".
I can see that the messages sent by the split node still contain the req and res properties, while the join node sends a message with only the payload and no req or res properties, which in my understanding is causing the problem.
What am I doing wrong?

The split join is wiping out msg.res.
Maybe try a different way to get the average. In a change node using JSONata
e.g

[{"id":"de29676d03629e55","type":"http in","z":"9e5f48c16729e4f0","name":"","url":"/avg","method":"post","upload":false,"swaggerDoc":"","x":210,"y":260,"wires":[["99333059.1d84d8","5fbb2e71.f07e3"]]},{"id":"99333059.1d84d8","type":"debug","z":"9e5f48c16729e4f0","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":580,"y":360,"wires":[]},{"id":"5fbb2e71.f07e3","type":"change","z":"9e5f48c16729e4f0","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$average($$.payload)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":260,"wires":[["40982d7b37a20db2"]]},{"id":"92706389.418af8","type":"http request","z":"9e5f48c16729e4f0","name":"","method":"POST","ret":"txt","paytoqs":"ignore","url":"http://192.168.1.25:1880/avg","tls":"","persist":false,"proxy":"","authType":"","x":350,"y":360,"wires":[["99333059.1d84d8"]]},{"id":"40982d7b37a20db2","type":"http response","z":"9e5f48c16729e4f0","name":"","statusCode":"","headers":{},"x":750,"y":200,"wires":[]},{"id":"b82acabf.83fe6","type":"inject","z":"9e5f48c16729e4f0","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[2,3,4]","payloadType":"json","x":160,"y":360,"wires":[["92706389.418af8"]]}]

Thank you. Calculating the average was just an example. I was hoping to find a way to use split/join in an HTTP flow.
You're saying "split join is wiping out msg.res" - but why is it doing that? Is this documented somewhere?

You can store msg.res or pass it around the split join.
e.g.

[{"id":"de29676d03629e55","type":"http in","z":"bf9e1e33.030598","name":"","url":"/avg","method":"post","upload":false,"swaggerDoc":"","x":310,"y":2080,"wires":[["8bef9ac2.090d98","ab3a1f0c.644358"]]},{"id":"8bef9ac2.090d98","type":"split","z":"bf9e1e33.030598","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":530,"y":2100,"wires":[["aff68009.2c852"]]},{"id":"ab3a1f0c.644358","type":"change","z":"bf9e1e33.030598","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"res","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":2040,"wires":[["83cf8d43.d815c8"]]},{"id":"aff68009.2c852","type":"join","z":"bf9e1e33.030598","name":"","mode":"reduce","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"","reduceRight":false,"reduceExp":"$A+payload","reduceInit":"0","reduceInitType":"num","reduceFixup":"$A/$N","x":670,"y":2100,"wires":[["5fbb2e71.f07e3"]]},{"id":"83cf8d43.d815c8","type":"join","z":"bf9e1e33.030598","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":990,"y":2080,"wires":[["5f7c49b2.30ff5"]]},{"id":"5fbb2e71.f07e3","type":"change","z":"bf9e1e33.030598","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"join","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":830,"y":2100,"wires":[["83cf8d43.d815c8"]]},{"id":"5f7c49b2.30ff5","type":"change","z":"bf9e1e33.030598","name":"","rules":[{"t":"move","p":"payload.join","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1190,"y":2080,"wires":[["40982d7b37a20db2"]]},{"id":"40982d7b37a20db2","type":"http response","z":"bf9e1e33.030598","name":"","statusCode":"","headers":{},"x":1130,"y":2020,"wires":[]},{"id":"b82acabf.83fe6","type":"inject","z":"bf9e1e33.030598","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[2,3,4]","payloadType":"json","x":260,"y":2180,"wires":[["92706389.418af8"]]},{"id":"92706389.418af8","type":"http request","z":"bf9e1e33.030598","name":"","method":"POST","ret":"txt","paytoqs":"ignore","url":"http://192.168.1.25:1880/avg","tls":"","persist":false,"proxy":"","authType":"","x":450,"y":2180,"wires":[["99333059.1d84d8"]]},{"id":"99333059.1d84d8","type":"debug","z":"bf9e1e33.030598","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":640,"y":2180,"wires":[]}]

Ok, thanks for the workaround.
If someone can explain why this is necessary (i.e., why can't join pass on msg.res?), I would be very interested.

Not sure it's necessary - possibly a bug. BUT I would only expect it work (easily) if using a split as well - so that every part has a .res on. I suspect it may be very easy to end up sending multiple res messages to the response node which would also cause a failure... but probably worth raising an issue to log it so we can investigate.

Added possible PR here - Join node in reduce mode doesn't keep existing msg properties by dceejay · Pull Request #3670 · node-red/node-red · GitHub