Possibly a bug in contrib-modbus or even in node-red core

Hi!
I need to sequentially poll several Modbus IDs connected to the same serial-to-TCP gateway. Because this gateway is a bit buggy and sometimes fail to manage poll queue (TCP to RS-485) in a propper manner, I'm forced to orchestrate the read sequence by designing Node-RED flows. Any Modbus ID in the middle of the poll chain can fail and block reading of the remaining IDs, since their poll nodes can't be triggered anymore.

The solution is well known for a long time: enable the "Empty msg on Modbus fail" option in Modbus-Getter node.

But there is a situation when the tactics described above (enabling the "Empty msg on Modbus fail" option) does not produce the expected effect.

Look at the flow below:
The first two nodes (KOM-A1-401-3-G27-QF1 and KOM-A1-401-3-G28-QF1) operate successfully without error, but the third node (KOM-A1-401-3-G29-QF1) is physically disabled and will therefore be polled, generating an error message.

The expected behavior of the KOM-A1-401-3-G30-QF1 and KOM-A1-401-3-G30-QF1* nodes is to process and poll their Modbus IDs.
This is true for the KOM-A1-401-3-G30-QF1* node, but the behavior of the KOM-A1-401-3-G30-QF1 node differs from the expected behavior—it will not be triggered by an incoming error message from the KOM-A1-401-3-G29-QF1 node.

After a series of experiments, I discovered a pattern.
The rule is as follows: if a polling error occurs in a Modbus-Getter node, an error message is generated. All subsequent Modbus-Getter nodes using the same server in their configuration become immune to such "messages" and lose the ability to be triggered by input anymore, except by sending them a message from the inject node. This ruins the flow logic.

An important note about what "the same server" means:
This is a situation where Modbus-Getter nodes have a server with the same name in their configuration.
Servers with different names but the same IP address are not considered to be the same.

In the example above all Modbus-Getter nodes configured by that "the same server", except one.
KOM-A1-401-3-G27-QF1,KOM-A1-401-3-G28-QF1,KOM-A1-401-3-G29-QF1 and KOM-A1-401-3-G30-QF1 nodes use server "A1-401-2-KOM-RS1"
KOM-A1-401-3-G30-QF1* use server "A1-401-2-KOM-RS1*"

Same IP's, different names and ... behavior :wink:

This looks like some kind of "poisoning" (by only one error message after a single failed poll) of some structure identified only by that "server name" deep inside the Node-RED underground.

The code for reproducibility of the situation is below:

[
    {
        "id": "dde6f0c9a59f7e85",
        "type": "tab",
        "label": "[G] A1-401-2-КОМ-RS1",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "c89ffa300dd5f4fd",
        "type": "modbus-getter",
        "z": "dde6f0c9a59f7e85",
        "name": "КОМ-А1-401-3-G29-QF1",
        "showStatusActivities": false,
        "showErrors": false,
        "showWarnings": true,
        "logIOActivities": false,
        "unitid": "29",
        "dataType": "HoldingRegister",
        "adr": "512",
        "quantity": "26",
        "server": "aa6ffc916a37a4e2",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": true,
        "keepMsgProperties": false,
        "delayOnStart": false,
        "enableDeformedMessages": false,
        "startDelayTime": "",
        "x": 1090,
        "y": 240,
        "wires": [
            [],
            [
                "c32340d007926fb0",
                "4d61b99ef14677f3",
                "55d3410d3e0ca24c"
            ]
        ]
    },
    {
        "id": "4d61b99ef14677f3",
        "type": "modbus-getter",
        "z": "dde6f0c9a59f7e85",
        "name": "КОМ-А1-401-3-G30-QF1",
        "showStatusActivities": false,
        "showErrors": false,
        "showWarnings": true,
        "logIOActivities": false,
        "unitid": "30",
        "dataType": "HoldingRegister",
        "adr": "512",
        "quantity": "26",
        "server": "aa6ffc916a37a4e2",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": true,
        "keepMsgProperties": false,
        "delayOnStart": false,
        "enableDeformedMessages": false,
        "startDelayTime": "",
        "x": 1430,
        "y": 140,
        "wires": [
            [],
            [
                "6e5cb43f69d51a08"
            ]
        ]
    },
    {
        "id": "c32340d007926fb0",
        "type": "function",
        "z": "dde6f0c9a59f7e85",
        "name": "[status]",
        "func": "if (msg.hasOwnProperty('error')) {\n    node.status({fill:\"red\",shape:\"ring\",text:\"ERR\"})\n}\nelse  { node.status({fill:\"green\",shape:\"ring\",text:\"OK\"});return msg};",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1060,
        "y": 320,
        "wires": [
            []
        ]
    },
    {
        "id": "55d3410d3e0ca24c",
        "type": "modbus-getter",
        "z": "dde6f0c9a59f7e85",
        "name": "КОМ-А1-401-3-G30-QF1*",
        "showStatusActivities": false,
        "showErrors": false,
        "showWarnings": true,
        "logIOActivities": false,
        "unitid": "30",
        "dataType": "HoldingRegister",
        "adr": "512",
        "quantity": "26",
        "server": "6ac3d731375d7956",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": true,
        "keepMsgProperties": false,
        "delayOnStart": false,
        "enableDeformedMessages": false,
        "startDelayTime": "",
        "x": 1450,
        "y": 380,
        "wires": [
            [],
            [
                "4baefcc3e2cf68ff"
            ]
        ]
    },
    {
        "id": "d04e09971c210041",
        "type": "comment",
        "z": "dde6f0c9a59f7e85",
        "name": "frosen by error generated in previous node",
        "info": "",
        "x": 1480,
        "y": 100,
        "wires": []
    },
    {
        "id": "072844693c0fdf6f",
        "type": "comment",
        "z": "dde6f0c9a59f7e85",
        "name": "works fine, can be triggered by error from previous node",
        "info": "",
        "x": 1540,
        "y": 340,
        "wires": []
    },
    {
        "id": "12b11b3d9c1972ac",
        "type": "comment",
        "z": "dde6f0c9a59f7e85",
        "name": "does't work, can't be triggered by error from previous node",
        "info": "",
        "x": 1530,
        "y": 60,
        "wires": []
    },
    {
        "id": "40a0c681ec122f68",
        "type": "inject",
        "z": "dde6f0c9a59f7e85",
        "name": "manual \"reset\"",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 1120,
        "y": 100,
        "wires": [
            [
                "4d61b99ef14677f3"
            ]
        ]
    },
    {
        "id": "1b5ee4f960f09b5b",
        "type": "modbus-getter",
        "z": "dde6f0c9a59f7e85",
        "name": "КОМ-А1-401-3-G28-QF1",
        "showStatusActivities": false,
        "showErrors": false,
        "showWarnings": true,
        "logIOActivities": false,
        "unitid": "28",
        "dataType": "HoldingRegister",
        "adr": "512",
        "quantity": "26",
        "server": "aa6ffc916a37a4e2",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": true,
        "keepMsgProperties": false,
        "delayOnStart": false,
        "enableDeformedMessages": false,
        "startDelayTime": "",
        "x": 770,
        "y": 240,
        "wires": [
            [],
            [
                "21dae06c9a78a618",
                "c89ffa300dd5f4fd"
            ]
        ]
    },
    {
        "id": "21dae06c9a78a618",
        "type": "function",
        "z": "dde6f0c9a59f7e85",
        "name": "[status]",
        "func": "if (msg.hasOwnProperty('error')) {\n    node.status({fill:\"red\",shape:\"ring\",text:\"ERR\"})\n}\nelse  { node.status({fill:\"green\",shape:\"ring\",text:\"OK\"});return msg};",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 740,
        "y": 320,
        "wires": [
            []
        ]
    },
    {
        "id": "6e5cb43f69d51a08",
        "type": "function",
        "z": "dde6f0c9a59f7e85",
        "name": "[status]",
        "func": "if (msg.hasOwnProperty('error')) {\n    node.status({fill:\"red\",shape:\"ring\",text:\"ERR\"})\n}\nelse  { node.status({fill:\"green\",shape:\"ring\",text:\"OK\"});return msg};",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1420,
        "y": 220,
        "wires": [
            []
        ]
    },
    {
        "id": "4baefcc3e2cf68ff",
        "type": "function",
        "z": "dde6f0c9a59f7e85",
        "name": "[status]",
        "func": "if (msg.hasOwnProperty('error')) {\n    node.status({fill:\"red\",shape:\"ring\",text:\"ERR\"})\n}\nelse  { node.status({fill:\"green\",shape:\"ring\",text:\"OK\"});return msg};",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1440,
        "y": 460,
        "wires": [
            []
        ]
    },
    {
        "id": "b9934493e5465c1c",
        "type": "modbus-getter",
        "z": "dde6f0c9a59f7e85",
        "name": "КОМ-А1-401-3-G27-QF1",
        "showStatusActivities": false,
        "showErrors": false,
        "showWarnings": true,
        "logIOActivities": false,
        "unitid": "27",
        "dataType": "HoldingRegister",
        "adr": "512",
        "quantity": "26",
        "server": "aa6ffc916a37a4e2",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": true,
        "keepMsgProperties": false,
        "delayOnStart": false,
        "enableDeformedMessages": false,
        "startDelayTime": "",
        "x": 490,
        "y": 240,
        "wires": [
            [],
            [
                "77757fa653785977",
                "1b5ee4f960f09b5b"
            ]
        ]
    },
    {
        "id": "77757fa653785977",
        "type": "function",
        "z": "dde6f0c9a59f7e85",
        "name": "[status]",
        "func": "if (msg.hasOwnProperty('error')) {\n    node.status({fill:\"red\",shape:\"ring\",text:\"ERR\"})\n}\nelse  { node.status({fill:\"green\",shape:\"ring\",text:\"OK\"});return msg};",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 480,
        "y": 320,
        "wires": [
            []
        ]
    },
    {
        "id": "54263a0a91c65c62",
        "type": "inject",
        "z": "dde6f0c9a59f7e85",
        "name": "push button :-)",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 130,
        "y": 240,
        "wires": [
            [
                "b9934493e5465c1c"
            ]
        ]
    },
    {
        "id": "aa6ffc916a37a4e2",
        "type": "modbus-client",
        "name": "A1-401-2-KOM-RS1",
        "clienttype": "tcp",
        "bufferCommands": true,
        "stateLogEnabled": false,
        "queueLogEnabled": false,
        "failureLogEnabled": true,
        "tcpHost": "10.30.44.20",
        "tcpPort": "502",
        "tcpType": "DEFAULT",
        "serialPort": "/dev/ttyUSB",
        "serialType": "RTU-BUFFERD",
        "serialBaudrate": "9600",
        "serialDatabits": "8",
        "serialStopbits": "1",
        "serialParity": "none",
        "serialConnectionDelay": "100",
        "serialAsciiResponseStartDelimiter": "0x3A",
        "unit_id": 1,
        "commandDelay": 1,
        "clientTimeout": 1000,
        "reconnectOnTimeout": true,
        "reconnectTimeout": 2000,
        "parallelUnitIdsAllowed": true,
        "showWarnings": true,
        "showLogs": true
    },
    {
        "id": "6ac3d731375d7956",
        "type": "modbus-client",
        "name": "A1-401-2-KOM-RS1*",
        "clienttype": "tcp",
        "bufferCommands": true,
        "stateLogEnabled": false,
        "queueLogEnabled": false,
        "failureLogEnabled": true,
        "tcpHost": "10.30.44.20",
        "tcpPort": 502,
        "tcpType": "DEFAULT",
        "serialPort": "/dev/ttyUSB",
        "serialType": "RTU-BUFFERD",
        "serialBaudrate": 9600,
        "serialDatabits": 8,
        "serialStopbits": 1,
        "serialParity": "none",
        "serialConnectionDelay": 100,
        "serialAsciiResponseStartDelimiter": "0x3A",
        "unit_id": 1,
        "commandDelay": 1,
        "clientTimeout": 1000,
        "reconnectOnTimeout": true,
        "reconnectTimeout": 2000,
        "parallelUnitIdsAllowed": true,
        "showErrors": false,
        "showWarnings": true,
        "showLogs": true
    },
    {
        "id": "3e8932246f8b15fd",
        "type": "global-config",
        "env": [],
        "modules": {
            "node-red-contrib-modbus": "5.45.2"
        }
    }
]

Node-RED version is 4.1.8, latest one at the time of this report writing.

I fixed this bug, including some others, with claude. I recommend buying a claude/cursor subscription and fixing it yourself. unfortunately, the developers abandoned the library and I don't see any point in trying to post my changes on github.

Do you mean node-red-contrib-modbus? What makes you think that it is abandoned.

To save the rest of us the cost of a claude subscription?

Dmitry, thanx a lot for your answer.

Hello. I had a similar problem with the modbus nodes.
As a test try to revert to version 5.23.3 before the developers of the node introduced a breaking change.
The older node version would always produce an "Empty msg on Modbus fail" which from what i understood is what you need for your flow logic.

To install the older version point your terminal to the node-red folder and run
npm i node-red-contrib-modbus@5.23.3

Hope it helps.

Its not abandoned but the developers have the Github issues set to auto-close after 60 days and they almost never consider or reply to the issues. (Which is understandable .. people have their full-time jobs and possibly not enough time to support the node)

Hmm, that is not good.

Modbus node is a pain to work with. Luckily I forced it to work, by using guaranteed output (after a set delay) and configurable amount of retry attemps. Attached it as file because it is so large. Take precaution to investigate it yourself before using, however it will not do anything malicious, behavior is only to send modbus read requests and optionally write to log file.
modbus_read.json (70.8 KB)