Truncation of hexadecimal input - known issue?

Hi There,

Screen Recording 2026-04-27 at 09.06.03-2

I'm sure someone else already noticed this but for me it's something that's new.

I happen to be using a large hexadecimal 0x2c652cee5922ed4d value which converts to the decimal 3199012512525905229. What the flow does is push the value to the debug panel so that I can convert between the two representations:

[{"id":"db7f8839c112b812","type":"inject","z":"1f9f1eefa7ae1c35","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0x2c652cee5922ed4d","payloadType":"num","x":5291,"y":852,"wires":[["46668d9326a62ccf"]]},{"id":"46668d9326a62ccf","type":"debug","z":"1f9f1eefa7ae1c35","name":"debug 14","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":5385,"y":946,"wires":[]}]

What is shown in the animation is the truncation of the hex to 0x2c652cee5922ee00 and the decimal accordingly to 3199012512525905400

This is a extremely subtle error and something that probably isn't that obvious. The only reason I spotted it was that I converted the hex using ddg first to get the correct value and then thought to use Node-RED to convert the hex value ... well that didn't really work!

Tested was version NR v4.0.9 - you mileage might well vary.

Cheers!

I think that is larger than the max integer that javascript can handle, which I believe, in hex, is 0x1 followed by 13 Fs.

That number far exceeds safe max integer: Number.MAX_SAFE_INTEGER - JavaScript | MDN

If your want to know why/how, there are tonnes of articles around the web that can do a better job of explaining it than I can.

I guess the question is should node red do something about that? Like use a library capable of true 64-bit integes?. Or automatically convert to bigint? Or something else? It's not an easy problem to solve without breaking something else downstream that doesn't also handle numbers greater than the max safe

Exactly that's what I was trying to point out - Node-RED provides me with a falsehood without indicating that. If there was a red star a blink error message or something else to tell me that the number shown is wrong, then I can handle that.

I would be for a error message or warning in the debug panel so that I and others can take actions when values are knowingly incorrect. Being able to handle the hex value correctly would be a second step in my opinion.

I don't think the debug panel will have any way of knowing, it is just showing what is in msg.payload. It is in the Inject node that the error occurs, ideally it should not allow you to specify a value that it cannot accurately put in the message.

The problem is that Number.MAX_SAFE_INTEGER is not the largest number that JavaScript will process, merely the largest number you can safely handle in calculations to get an accurate answer.

So setting a number higher than that is not an error.

Perhaps, however, we should consider it a bug that the debug node does not give a warning. It could use Number.isSafeInteger() - however, I suspect that this would involve a fair bit more processing and debug can already slow things down.

Have you tried outputting just to console using the debug node? Does that have the same issue?

Instead of packing more processing into the debug node, perhaps we should consider adding a "Limitations" page to the documentation for Node-RED? We could use that to collect the issues that JavaScript forces on us?

Couldn't that be done in the inject node to check the number is safe?

The trouble either way is - what to check? If you are inputting or outputting a complex object, how far down do you check for large numbers?

Good point.

node-red-builder-1  | {
node-red-builder-1  |   _msgid: '5af98ba99011bc92',
node-red-builder-1  |   payload: 3199012512525905400
node-red-builder-1  | }

in the console it is also wrong.

Strangely I tested using Erlang-Red and the console was right, i.e.

DEBUG [<<"debug 14">>]: #{'_msgid' => <<"4a6998ee04ab60a1">>,
                          '_ws' => ws0aef38,
                          <<"payload">> => 3199012512525905229}

but the debug panel (in Erlang-Red) was also wrong, i.e., showing a truncated value.

This for me suggests that there are two truncations happening, one internally on the NodeJS side and one on the frontend in the debug panel.

That does not surprise me as each will be going through its own processing I think.

Nobody sensible claims that JavaScript is a "good" computer language. Merely the one used everywhere! :smiley: