#16054·thingsboard

"action - rpc call request" rule node failing to send WriteReplace message to a LwM2M unsigned int resource

Author: pol-basCreated Aug 23, 2026Updated Aug 29, 2026
Labelsunconfirmed

Describe the bug An "action rpc call request" rule node returns "BAD_REQUEST" error after a request to update an UNSIGNED INTEGER LwM2M resource with an unsigned value. Using wireshark I can confirm the message is never issued from Thingsboard server to device.

My Server Environment

  • own setup
    • Deployment: monolith
    • Deployment type: rpm on an AWS EC2 instance
    • ThingsBoard Version 4.2.0
    • Community Edition
    • OS Name and Version: Amazon Linux 2023, Version 2023.10.20260105

My Device Device firmware built on a STM32L4P5 MCU using a cellular 4G modem implementing a LwM2M version 1.1 client (based on Wakaama library)

My Client Workstation

  • OS: Windows 11
  • Browser: Microsoft Edge
  • Version: 151.0.4129.101

To Reproduce I am showing the rule chain piece allowing to reproduce the behavior:

Explanation: Node #1: a RPC call request reading resource /38031/0/7 is read from device. Message payload: { "method": "Read", "params": { "id": "/38031/0/7" }. Message type: RPC_CALL_FROM_SERVER_TO_DEVICE. Resource /38031/0/7 contains a hash of current device's configuration.

Node #2: a switch filter node comparing device's configuration hash coming from node #1 against server stored configuration hash for that device. If both do match, next action routed via the "AlreadyInSync" path; otherwise the next action/node is routed via the "HashMismatch" path.

Node #3: a transformation-script node in charge of parsing the message to be sent to the device to update its configuration (stored at device's resource /38031/0/1, defined as an 32-bit unsigned integer). The script implemented in node #3 is the following:

var portMask = JSON.parse(metadata.ss_portInputMask);
var maskInt = 0;
for (var i = 0; i < portMask.size(); i++) {
    if (portMask[i] == true) {
        maskInt = maskInt | (1 << i);
    }
}
// use an unsigned zero-fill right shift in TBEL to force a 32-bit unsigned integer
var maskUnsigned = maskInt >>> 0;
var msg = {
    "method": "WriteReplace",
    "params": {
        "id": "/38031/0/1",
        "value": maskUnsigned
    }
};
return { msg: msg, metadata: metadata, msgType: "RPC_CALL_FROM_SERVER_TO_DEVICE" };

Node #4: an "action - rpc call request" rule node in charge of sending parsed message in previous node and send it back to device.

See below the simulation results by debugging node #4:

  • Image with captured events:
  • Detail of "Data" and "Metadata" message contents:

INPUT MSG

Event time: 2026-08-23 10:08:34.463

Data: { "method": "WriteReplace", "params": { "id": "/38031/0/1", "value": 13 } }

Metadata: { "deviceLabel": "Develop device", "deviceName": "867255079904415", "deviceType": "LwM2M_device_profile", "expirationTime": "1787472566290", "scope": "SERVER_SCOPE", "ss_active": "true", "ss_configurationChanged": "true", "ss_portInputMask": "[true,false,true,true,false,false,false,false,false,false,false,false]", "ss_processingRules": "[{"ruleID":0,"ruleName":"REGLA_0","rulePyld":[0,1,2,3,4,5,6,7,8,9,10,11,12]}, {"ruleID":1,"ruleName":"REGLA_1","rulePyld":[0,0,0,0,1,1,1,1,2,2,2,2,3]}]", "ss_ruleAlarmMask": " [false,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]" }

OUPUT MSG #1

Event time: 2026-08-23 10:08:34.463

Data: { "method": "WriteReplace", "params": { "id": "/38031/0/1", "value": 13 } }

Metadata: { "deviceLabel": "Develop device", "deviceName": "867255079904415", "deviceType": "LwM2M_device_profile", "expirationTime": "1787472566290", "scope": "SERVER_SCOPE", "ss_active": "true", "ss_configurationChanged": "true", "ss_portInputMask": "[true,false,true,true,false,false,false,false,false,false,false,false]", "ss_processingRules": "[{"ruleID":0,"ruleName":"REGLA_0","rulePyld":[0,1,2,3,4,5,6,7,8,9,10,11,12]},{"ruleID":1,"ruleName":"REGLA_1","rulePyld":[0,0,0,0,1,1,1,1,2,2,2,2,3]}]", "ss_ruleAlarmMask": "[false,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]" }

OUTPUT MSG #2

Event time: 2026-08-23 10:08:34.470

Data: { "result": "BAD_REQUEST", "error": "Resource id=/38031/0/1, value = 13, class = Integer. Format value is bad. Value for this Single Resource must be UNSIGNED_INTEGER!" }

Metadata: { "deviceLabel": "Develop device", "deviceName": "867255079904415", "deviceType": "LwM2M_device_profile", "expirationTime": "1787472566290", "scope": "SERVER_SCOPE", "ss_active": "true", "ss_configurationChanged": "true", "ss_portInputMask": "[true,false,true,true,false,false,false,false,false,false,false,false]", "ss_processingRules": "[{"ruleID":0,"ruleName":"REGLA_0","rulePyld":[0,1,2,3,4,5,6,7,8,9,10,11,12]},{"ruleID":1,"ruleName":"REGLA_1","rulePyld":[0,0,0,0,1,1,1,1,2,2,2,2,3]}]", "ss_ruleAlarmMask": "[false,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]" }

Conclusion Output shown in output message #2 as "BAD_REQUEST" is not correct as value "13" is an unsigned integer. I tried to force the node #3 TBEL code ways to enforce unsigned integer for the "value" piece but in all cases the outcome is the same.


Disclaimer

We appreciate your contribution whether it is a bug report, feature request, or pull request with improvement (hopefully). Please comply with the Community ethics policy, and do not expect us to answer your requests immediately. Also, do not treat GitHub issues as a support channel.