# Split should send complete message once all has been split

**URL:** <https://discourse.nodered.org/t/split-should-send-complete-message-once-all-has-been-split/100069>\
**Category:** General\
**Tags:** split\
**Created:** [2 January 2026 08:01 UTC](https://discourse.nodered.org/t/split-should-send-complete-message-once-all-has-been-split/100069 "2026-01-02T08:01:19Z")\
**Posts on this page:** 9\
**Page:** 2

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [3 January 2026 09:27 UTC](https://discourse.nodered.org/t/split-should-send-complete-message-once-all-has-been-split/100069/21 "2026-01-03T09:27:43Z")

</div>

> [@Colin](#):
>
> There is no solution to that.

That's not the answer 😉 Question is, what is a good practical workaround - for example doing the final join _after_ the computation (as the flow solution above).

That won't work if messages are dropped so that your idea of

> [@Colin](#):
>
> One solution would be to mark messages to be dropped

Which would fix that problem too.

So basically moving the join that generates the final complete message as close as possible to the joins is one way of _reducing_ the risk of failure.

But yes, there is no guarantee that some message aren't slowed down by external dark matter radiation.

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [3 January 2026 09:40 UTC](https://discourse.nodered.org/t/split-should-send-complete-message-once-all-has-been-split/100069/22 "2026-01-03T09:40:46Z")

</div>

I don't think there is a perfect general solution for all cases - but I think there can be correct solutions for most individual cases. We do have mitigations in place to try to help - eg the array ordering as per I mentioned previously. Also the switch node has an option to recreate sequences - which can be used to "patch up" the parts as they are switched/filtered - so that they can be rejoined later. eg see this example using your scenario above.

```auto
[{"id":"bc5f86db20063fba","type":"function","z":"8f7d7811a9253b8f","name":"drop even numbers","func":"if (msg.payload % 2 === 0) { msg.payload = null }\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":452.5,"y":512.5,"wires":[["d934cee75db61d51"]]},{"id":"a32fc602b0ecc67e","type":"delay","z":"8f7d7811a9253b8f","name":"","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":390,"y":412.5,"wires":[["4d3b2998800ee242","bc5f86db20063fba"]]},{"id":"d934cee75db61d51","type":"join","z":"8f7d7811a9253b8f","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","useparts":false,"accumulate":"false","timeout":"","count":"","reduceRight":false,"x":532.5,"y":562.5,"wires":[["12347b7057460c89"]]},{"id":"0984ac1bb6342f05","type":"switch","z":"8f7d7811a9253b8f","name":"swicth > 4","property":"payload","propertyType":"msg","rules":[{"t":"gt","v":"4","vt":"num"},{"t":"lte","v":"4","vt":"num"}],"checkall":"true","repair":true,"outputs":2,"x":225,"y":437.5,"wires":[["a32fc602b0ecc67e"],["502f5bf797b3c220"]]},{"id":"4d3b2998800ee242","type":"debug","z":"8f7d7811a9253b8f","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":565,"y":400,"wires":[]},{"id":"12347b7057460c89","type":"debug","z":"8f7d7811a9253b8f","name":"debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":692.5,"y":562.5,"wires":[]},{"id":"94461abdba5c5882","type":"split","z":"8f7d7811a9253b8f","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","property":"payload","x":417.5,"y":325,"wires":[["0984ac1bb6342f05"]]},{"id":"502f5bf797b3c220","type":"delay","z":"8f7d7811a9253b8f","name":"","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":397.5,"y":462.5,"wires":[["5af83a479eae5acb"]]},{"id":"034e58bbf2a5d185","type":"inject","z":"8f7d7811a9253b8f","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[0,1,2,3,4,5,6,7,8,9]","payloadType":"json","x":232.5,"y":325,"wires":[["94461abdba5c5882"]]},{"id":"5af83a479eae5acb","type":"join","z":"8f7d7811a9253b8f","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","useparts":false,"accumulate":"false","timeout":"","count":"","reduceRight":false,"x":557.5,"y":462.5,"wires":[["30a8fab04feeaa50"]]},{"id":"30a8fab04feeaa50","type":"debug","z":"8f7d7811a9253b8f","name":"debug 3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":722.5,"y":462.5,"wires":[]}]

```

But yes - can be very easy to break - which is why I don't think there is a general answer for all situations.

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [3 January 2026 10:01 UTC](https://discourse.nodered.org/t/split-should-send-complete-message-once-all-has-been-split/100069/23 "2026-01-03T10:01:59Z")

</div>

> [@dceejay](#):
>
> option to recreate sequences

Wow, ok that's nice feature -

![Screenshot 2026-01-03 at 10.54.40](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/d/4/d4e45761c70e0251228361b62f20b14776cdd0bc.png)

Never noticed/understood before what that does.

Ok, so it uses the message count and index values on the split to know when a sequence comes to an end and only then does it send out it's own messages. In your example, both branches after the filter(switch node) have correct counts on the `parts` attribute on the message.

That then solves the split-filter-collect-without-dropped-messages use-case. Because each branch after the switch node has it's own collection of messages upon which it can join.

Nice!

If I was still writing my blog, I would do a write up on that! --\> [FlowHub: [Layout Learnings] Split Filter Collect flow](https://flowhub.org/f/3291ecd7eaad33cd)

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [3 January 2026 15:53 UTC](https://discourse.nodered.org/t/split-should-send-complete-message-once-all-has-been-split/100069/24 "2026-01-03T15:53:31Z")

</div>

If you add in Colin's suggestion - and rather than drop messages completely, replace them with nulls if some condition occurs - then you can easily re-filter after re-joining them. eg as below - which is one way to work around the split-filter-collect-WITH-dropped-messages use-case

```auto
[{"id":"c295fef495b72c5e","type":"function","z":"8f7d7811a9253b8f","name":"finally filter out null returns","func":"msg.payload = msg.payload.filter((val) => val !== null);\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":600,"wires":[["12347b7057460c89"]]},{"id":"d934cee75db61d51","type":"join","z":"8f7d7811a9253b8f","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","useparts":false,"accumulate":"false","timeout":"","count":"","reduceRight":false,"x":562.5,"y":525,"wires":[["c295fef495b72c5e"]]},{"id":"12347b7057460c89","type":"debug","z":"8f7d7811a9253b8f","name":"debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":615,"y":600,"wires":[]},{"id":"bc5f86db20063fba","type":"function","z":"8f7d7811a9253b8f","name":"drop even numbers","func":"if (msg.payload % 2 === 0) { msg.payload = null }\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":525,"wires":[["d934cee75db61d51"]]},{"id":"a32fc602b0ecc67e","type":"delay","z":"8f7d7811a9253b8f","name":"","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":335,"y":462.5,"wires":[["4d3b2998800ee242","bc5f86db20063fba"]]},{"id":"0984ac1bb6342f05","type":"switch","z":"8f7d7811a9253b8f","name":"swicth > 4","property":"payload","propertyType":"msg","rules":[{"t":"lte","v":"4","vt":"num"},{"t":"gt","v":"4","vt":"num"}],"checkall":"true","repair":true,"outputs":2,"x":162,"y":445.5,"wires":[["502f5bf797b3c220"],["a32fc602b0ecc67e"]]},{"id":"4d3b2998800ee242","type":"debug","z":"8f7d7811a9253b8f","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":510,"y":462.5,"wires":[]},{"id":"94461abdba5c5882","type":"split","z":"8f7d7811a9253b8f","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","property":"payload","x":354.5,"y":333,"wires":[["0984ac1bb6342f05"]]},{"id":"502f5bf797b3c220","type":"delay","z":"8f7d7811a9253b8f","name":"","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":335,"y":412.5,"wires":[["5af83a479eae5acb"]]},{"id":"034e58bbf2a5d185","type":"inject","z":"8f7d7811a9253b8f","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[0,1,2,3,4,5,6,7,8,9]","payloadType":"json","x":169.5,"y":333,"wires":[["94461abdba5c5882"]]},{"id":"5af83a479eae5acb","type":"join","z":"8f7d7811a9253b8f","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","useparts":false,"accumulate":"false","timeout":"","count":"","reduceRight":false,"x":500,"y":412.5,"wires":[["30a8fab04feeaa50"]]},{"id":"30a8fab04feeaa50","type":"debug","z":"8f7d7811a9253b8f","name":"debug 3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":660,"y":412.5,"wires":[]}]

```

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [3 January 2026 16:08 UTC](https://discourse.nodered.org/t/split-should-send-complete-message-once-all-has-been-split/100069/25 "2026-01-03T16:08:39Z")

</div>

> [@gregorius](#):
>
> there is no guarantee that some message aren't slowed down by external dark matter radiation.

If there is nothing asynchronous in the intervening flows then in fact the flow is deterministic, so external dark matter radiation will not slow them down. The strategy used is documented somewhere but I can't find it. If I remember correctly, at its simplest, when a node is given the processor it services one message from its input queue and then gives up the processor. Every other node will be given the processor before the first node gets it again.

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [3 January 2026 17:50 UTC](https://discourse.nodered.org/t/split-should-send-complete-message-once-all-has-been-split/100069/26 "2026-01-03T17:50:09Z")

</div>

Do you mean this page --\> [Messaging Hooks : Node-RED](https://nodered.org/docs/api/hooks/messaging/) that has a diagram describing the message passing?

> [@Colin](#):
>
> processor it services one message

I want to avoid making assumption about the processing model underlying the flow diagrams. I.e. Erlang-Red being multi-processor/thread so that flows like this are truly depended on message arrival and not when they get processor time.

And also FBP makes no assumptions other than everything is independent of anything else!

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [3 January 2026 20:29 UTC](https://discourse.nodered.org/t/split-should-send-complete-message-once-all-has-been-split/100069/27 "2026-01-03T20:29:21Z")

</div>

> [@gregorius](#):
>
> Erlang-Red being multi-processor/thread so that flows like this are truly depended on message arrival and not when they get processor time

In that case then the effects of dark matter radiation, not to mention the improbabilities induced by a nice hot cup of tea, may indeed be factors that you must allow for.

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [3 January 2026 20:48 UTC](https://discourse.nodered.org/t/split-should-send-complete-message-once-all-has-been-split/100069/28 "2026-01-03T20:48:24Z")

</div>

> Probability factor of one to one. We have normality. I repeat, we have normality. Anything you still can't cope with is therefore your own problem.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [17 January 2026 20:49 UTC](https://discourse.nodered.org/t/split-should-send-complete-message-once-all-has-been-split/100069/29 "2026-01-17T20:49:22Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.

[Previous page](https://discourse.nodered.org/t/split-should-send-complete-message-once-all-has-been-split/100069.md?page=1)
