You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Disabling "Enable global context store" in the server config node has no effect at runtime if the stored config node in flows.json does not contain a version property. The palette keeps writing all entity states to global.homeassistant on every state change, even though the deployed config clearly contains "enableGlobalContextStore": false.
Root cause (verified against the v0.80.3 sources):
On startup, config-server/index.ts runs the stored config through migrate(config):
this.config=migrate(config);
src/helpers/migrate.ts only skips migrations when a version property exists:
If version is undefined (which is the case for server config nodes created before the versioning mechanism was introduced and apparently never backfilled on save), all migrations from 0 to 6 are re-applied on every startup.
Migration version 5 in src/nodes/config-server/migrations.ts sets the flag unconditionally, overwriting whatever the user configured:
The migrated config is only used in memory and never written back to flows.json, so the editor and the deployed flows keep showing false while the running node behaves as if it were true. There is no visible indication of the mismatch.
Note that other migrations do get reflected in the saved config when the node is edited (e.g. ha_boolean was converted from "" to [] on my instance), but the version property itself was never persisted, so the runtime migration keeps re-running forever.
Impact
This is mostly invisible with the default in-memory context store. It becomes a real problem when a persistent context store is configured (contextStorage: { default: { module: "localfilesystem" } }): the full entity/state mirror (>1 MB on a typical installation, updated on every state change) is then flushed to disk continuously — unnecessary flash wear and CPU on typical Home Assistant hardware — and there is no way to turn it off via the UI.
To Reproduce
Use a server config node whose entry in flows.json has noversion property (legacy node; removing the property manually reproduces it as well).
Open the server config, untick Enable global context store, deploy, restart Node-RED.
Open the context sidebar → Global: homeassistant is (re)created and grows with every state change.
Delete the homeassistant key in the context sidebar → it is immediately repopulated.
Verify via the admin API (GET /flows) that the deployed config really contains "enableGlobalContextStore": false.
Expected behavior
A migration must not overwrite an explicitly configured value; migration v5 should only set a default when the property is absent, e.g.
Additionally/alternatively: ensure the version property is persisted when a config node is saved from the editor, so runtime migrations don't silently re-run on every start.
Screenshots
No response
Example Flow
Environment Information
node-red-contrib-home-assistant-websocket: 0.80.3
Node-RED: v5.0.0 (Home Assistant Community Add-on v22.0.0)
Node.js: v24.16.0
Home Assistant: 2026.6.4
Context storage: localfilesystem as default store (memory default hides the symptom)
Additional context
Workaround
Warning
Adding version alone can break your flows: it stops all migrations from running, so any field in your stored config that still relies on a migration default will be used raw. In my case "ha_boolean": [] (previously fixed up by migration v1 on every start) caused all boolean state matching to silently fail — motion sensors, smoke detectors etc. stopped triggering.
Safe procedure:
Stop Node-RED, back up flows.json.
On the server config node, add "version": 6and make sure the migration-provided fields hold sane values — most importantly "ha_boolean": ["y", "yes", "true", "on", "home", "open"] (must not be empty). The status* and *Selector fields from migrations v3/v4 have code-side fallbacks and are uncritical.
Start Node-RED, delete the stale homeassistant key via the context sidebar (Global scope).
Verify: the key stays deleted, and boolean-based state nodes still trigger.
After this, the setting is honored and the context store remains clean.
Describe the bug
Disabling "Enable global context store" in the server config node has no effect at runtime if the stored config node in
flows.jsondoes not contain aversionproperty. The palette keeps writing all entity states toglobal.homeassistanton every state change, even though the deployed config clearly contains"enableGlobalContextStore": false.Root cause (verified against the v0.80.3 sources):
On startup,
config-server/index.tsruns the stored config throughmigrate(config):src/helpers/migrate.tsonly skips migrations when aversionproperty exists:If
versionisundefined(which is the case for server config nodes created before the versioning mechanism was introduced and apparently never backfilled on save), all migrations from 0 to 6 are re-applied on every startup.Migration version 5 in
src/nodes/config-server/migrations.tssets the flag unconditionally, overwriting whatever the user configured:The migrated config is only used in memory and never written back to
flows.json, so the editor and the deployed flows keep showingfalsewhile the running node behaves as if it weretrue. There is no visible indication of the mismatch.Note that other migrations do get reflected in the saved config when the node is edited (e.g.
ha_booleanwas converted from""to[]on my instance), but theversionproperty itself was never persisted, so the runtime migration keeps re-running forever.Impact
This is mostly invisible with the default in-memory context store. It becomes a real problem when a persistent context store is configured (
contextStorage: { default: { module: "localfilesystem" } }): the full entity/state mirror (>1 MB on a typical installation, updated on every state change) is then flushed to disk continuously — unnecessary flash wear and CPU on typical Home Assistant hardware — and there is no way to turn it off via the UI.To Reproduce
flows.jsonhas noversionproperty (legacy node; removing the property manually reproduces it as well).homeassistantis (re)created and grows with every state change.homeassistantkey in the context sidebar → it is immediately repopulated.GET /flows) that the deployed config really contains"enableGlobalContextStore": false.Expected behavior
A migration must not overwrite an explicitly configured value; migration v5 should only set a default when the property is absent, e.g.
Additionally/alternatively: ensure the
versionproperty is persisted when a config node is saved from the editor, so runtime migrations don't silently re-run on every start.Screenshots
No response
Example Flow
Environment Information
localfilesystemas default store (memory default hides the symptom)Additional context
Workaround
Warning
Adding
versionalone can break your flows: it stops all migrations from running, so any field in your stored config that still relies on a migration default will be used raw. In my case"ha_boolean": [](previously fixed up by migration v1 on every start) caused all boolean state matching to silently fail — motion sensors, smoke detectors etc. stopped triggering.Safe procedure:
flows.json."version": 6and make sure the migration-provided fields hold sane values — most importantly"ha_boolean": ["y", "yes", "true", "on", "home", "open"](must not be empty). Thestatus*and*Selectorfields from migrations v3/v4 have code-side fallbacks and are uncritical.homeassistantkey via the context sidebar (Global scope).After this, the setting is honored and the context store remains clean.