Node-Red notify message preparation - 'extra keys not allowed'

Hi there everyone. I’ve got a little issue with some coding in Node-Red.
This is a combination of 2 notification styles I’ve picked up along the way, and when I’m using just ‘Title’ and ‘Message’, the script works.
Once I try to add a whole lot of extra data, it goes wrong…

The error I get is:
HomeAssistantError: extra keys not allowed @ data[‘push’]

But I cannot tell why I can pass all this in the same field, just not prepared by another block… Hopefully someone can point out where i’m going wrong and fix it?

[
    {
        "id": "32e743b03d134851",
        "type": "function",
        "z": "607bb843ccfc0b02",
        "g": "91bb6dcd62693683",
        "name": "Prepare message",
        "func": "msg.payload = {\n    title: \"DE GARAGE STAAT NOG OPEN\",\n    message: \"Moet ze dicht, of laat je ze open?\",\n    data: {\n        push: {\n            sound: {\n                name: \"default\",\n                critical: 1,\n                volume: 1\n            }\n        },\n        actions: [\n            {\n                title: \"Garage OPEN\",\n                action: \"GARAGE_OPEN\"\n            },\n            {\n                title: \"Garage DICHT\",\n                action: \"GARAGE_DICHT\"\n            }\n        ],\n        persistent: true,\n        tag: \"persistent\",\n        priority: \"high\",\n        channel: \"ALARM\",\n        importance: \"high\",\n        ttl: 0\n    }\n};\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 810,
        "y": 1020,
        "wires": [
            [
                "b6d8d7402d3e3b13",
                "74031e66c4047f4c"
            ]
        ],
        "info": "Verwerkt de foutmelding en stelt de payload in."
    },
    {
        "id": "b6d8d7402d3e3b13",
        "type": "api-call-service",
        "z": "607bb843ccfc0b02",
        "g": "91bb6dcd62693683",
        "name": "Notify Edge 50 Ultra",
        "server": "6b06bb9d.c086a4",
        "version": 7,
        "debugenabled": false,
        "action": "notify.mobile_app_motorola_edge_50_ultra",
        "floorId": [],
        "areaId": [],
        "deviceId": [],
        "entityId": [],
        "labelId": [],
        "data": "msg.payload",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "all",
        "blockInputOverrides": false,
        "domain": "notify",
        "service": "mobile_app_motorola_edge_50_ultra",
        "x": 1080,
        "y": 980,
        "wires": [
            []
        ],
        "info": "Stuurt een notificatie naar je mobiele apparaat met de foutmelding."
    },
    {
        "id": "6b06bb9d.c086a4",
        "type": "server",
        "name": "Home Assistant",
        "addon": true,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "",
        "connectionDelay": false,
        "cacheJson": false,
        "heartbeat": false,
        "heartbeatInterval": "",
        "statusSeparator": "",
        "enableGlobalContextStore": false
    }
]

The msg.payload looks a little like this:

{"title":"DE GARAGE STAAT NOG OPEN","message":"Moet ze dicht, of laat je ze open?","data":{"push":{"sound":{"name":"default","critical":1,"volume":1}},"actions":[{"title":"Garage OPEN","action":"GARAGE_OPEN"},{"title":"Garage DICHT","action":"GARAGE_DICHT"}],"persistent":true,"tag":"persistent","priority":"high","channel":"ALARM","importance":"high","ttl":0}}

Just to be clear what it is I want, because it contains Dutch text, which may be difficult to read to most. This is a piece of a script that’s used to check up on the garage door. If it’s open after a certain time of day, or has been open for too long, I get a message.
And the why for the extra block is, this way I can prepare the message once, and then send it tot multiple phones. Changing the text for all instances is less painful this way.

Thank you for reading this, and thank you in advance for your help!

To add some extra info. If I just take the msg.payload and plunk that in the data field of my notification, everything works as desired…

[
    {
        "id": "3e41c5cc11f7c6d6",
        "type": "api-call-service",
        "z": "607bb843ccfc0b02",
        "g": "91bb6dcd62693683",
        "name": "Notify Edge 50 Ultra",
        "server": "6b06bb9d.c086a4",
        "version": 7,
        "debugenabled": false,
        "action": "notify.mobile_app_motorola_edge_50_ultra",
        "floorId": [],
        "areaId": [],
        "deviceId": [],
        "entityId": [],
        "labelId": [],
        "data": "{\"title\":\"DE GARAGE STAAT NOG OPEN\",\"message\":\"Moet ze dicht, of laat je ze open?\",\"data\":{\"push\":{\"sound\":{\"name\":\"default\",\"critical\":1,\"volume\":1}},\"actions\":[{\"title\":\"Garage OPEN\",\"action\":\"GARAGE_OPEN\"},{\"title\":\"Garage DICHT\",\"action\":\"GARAGE_DICHT\"}],\"persistent\":true,\"tag\":\"persistent\",\"priority\":\"high\",\"channel\":\"ALARM\",\"importance\":\"high\",\"ttl\":0}}",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "all",
        "blockInputOverrides": false,
        "domain": "notify",
        "service": "mobile_app_motorola_edge_50_ultra",
        "x": 620,
        "y": 1140,
        "wires": [
            []
        ]
    },
    {
        "id": "6b06bb9d.c086a4",
        "type": "server",
        "name": "Home Assistant",
        "addon": true,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "",
        "connectionDelay": false,
        "cacheJson": false,
        "heartbeat": false,
        "heartbeatInterval": "",
        "statusSeparator": "",
        "enableGlobalContextStore": false
    }
]

The “action” node accepts input overrides via the msg.payload object. One of these overrides is msg.payload.data, which replaces the node’s configured “data” field. Since your msg.payload already contains a data property, it’s unintentionally overriding the expected configuration.

If you enable “Show debug information,” you’ll see that the payload sent to Home Assistant isn’t what you expect, which is causing the error.

Possible fixes:

  • Enable “Block input overrides” in the node settings.
  • Leave the “data” field empty in the node config and move your current msg.payload to msg.payload.data so it correctly overrides the local config.
1 Like

Thank you for your insightfull solution @Kermit + debugging help!
The ‘Block input overrides’ solution is the quickest fix, but I guess the other way (leaving data field empty and sending to msg.payload.data) is the ‘better’ fix?
Or are they on par?

I’m fairly new to Node-Red and I want to learn the best ways as I go along…

P.S.
I’ve tried the second way and replaced the first line of my script to ‘msg.payload.data = {’ & left the Data field empty. But this results in another error:
HomeAssistantError: required key not provided @ data[‘message’]

I’ll try to fix this myself and come back on this if I’m unable to fix it myself…

Yes, both approaches achieve the same result—neither is inherently better than the other. It just depends on your preference and use case.

1 Like