Cannot convert object to primitive value - JSON expression

I’m getting repeated debug entries linked to an events state node with a JSON expression:

{"__enc__":true,"type":"error","data":{"name":"TypeError","message":"Cannot convert object to primitive value","stack":"TypeError: Cannot convert object to primitive value\n    at _.getComparatorResult (/config/node_modules/node-red-contrib-home-assistant-websocket/dist/common/services/ComparatorService.js:1:1718)\n    at E.onHaEventsStateChanged (/config/node_modules/node-red-contrib-home-assistant-websocket/dist/nodes/events-state/EventsStateController.js:1:2478)\n    at EventEmitter.<anonymous> (/config/node_modules/node-red-contrib-home-assistant-websocket/dist/common/events/Events.js:1:779)"}}

This is the JSON expression:

{"temperature": $number($entities("input_number.pool_target_temp").state)}

This is probably contributing to my performance issues I posted about here.

This node has only recently started throwing this error in Node-RED.

Ohhhh… I may have found and fixed the issue here:

This was previously set to “as string.” So far… looking OK.

I would be very surprised if this has ever worked.

The Events: state node has a conditional “If State” test, which you are using.

You have set the condition test to >= which is a [numeric] state-value comparator, against the literal value in the following field.

You have set the value-field to use the JSONata expression, which is returning an object. Something like {"temperature": 27}

The bit inside the JSONata expression is most likely working as you intended. The $entities() function gets the entity object for the pool-target-temperature, and then the state value is converted into a number.

First issue would be when the entity state is “unknown” or “unavailable”. The $number() function in JSONata fails with a terminal error if the function is given a string that cannot be parsed as a number.

Second issue would be the node attempting to compare the pool heater entity state value against the object. Regardless of whether you have the [deprecated] state casting set or not, the subject entity state value being either a number or a string, you are comparing

27 >= {“temperature”: 27} or
“27” >= {“temperature”: 27}

and the node is saying

as the node internal processing cannot turn the RHS object into a number / string at this point.

Further:

Sorry, no. This is only the Output Properties, which is for the output message and has nothing to do with the internal node operation.

To correct this, you need to retain the “Pool Heater: Water temperature” entity state as a string, and perform the entire test within one JSONata expression. Note that the comparator “>=” does not always work for string values representing un-formatted numbers. “3” comes after “21”, unfortunately.

So, if you were to set the “If State” comparator test to “JSONata”, then the following field, holding a JSONata expression, must evaluate to true / false, with true being the “If State” succeeds result.

A full expression would be

$number($entity().state) >= $number($entities("input_number.pool_target_temp").state)

which obtains the state value of the node subject entity (Pool Heater - Water Temperature), as well as the state value of the pool-target-temperature. Converting both to a number means the logic test >= will return a Boolean value from the expression.

However, if either entity state is “unavailable” or “unknown” then the $number() function fails. A bit of extra code can address this, returning false overall, assuming that that is the fallback result you wish for.

(
    $pool:=$entity().state;
    $target:=$entities("input_number.pool_target_temp").state;
        
    $pt:= $pool in ["unavailable", "unknown"] ? 0 : $number($pool);
    $tt:= $target in ["unavailable", "unknown"] ? 100 : $number($target);

    $pt >= $tt;
)

The general principle is to return true if pool temperature is >= target temperature, with the pool temperature resorting to 0 and the target temperature to 100 if either entity state value is unavailable or unknown. You can choose your own numbers to suit your situation.

This code has been tested as far as I am able to.

Thank you! I’ll give this a shot. For context… I’ve had this flow in place as-is for literal years, and it’s never resulted in a debug error in Node-RED. Maybe I’ve never seen it evaluated. Not sure, because I haven’t touched it in a long time.

This code resolves in the node just fine. It’ll be a bit before I can test its function for real.

The WebSocket nodes do get updated quite regularly. A recent change deprecated the state-casting, so whereas previously the entity state was cast to a number at the start of the node operation, it now remains as a string.

It may have been that the internal code did see the object from the JSONata code, and did extract the single key-value as a number. Or perhaps the conditional test between number and object did “work”, just returning false every time.

It may be that debug messages have been improved, so that this error is now being reported.

Whichever, a test of ‘string >= object’ certainly does not work now!

FYI there was a JSONata-related bug introduced in Node-RED 5.0.2 that was not fully reverted until version 5.0.4. The Node-RED community app is still on 5.0.2 as of app version 22.0.1, but you could get 5.0.4 using the Node-RED Plus app:

Open your Home Assistant instance and show the dashboard of an app.