From 3aaa8c15464fbcfbdd7af17a0a46a2fc5df1eabd Mon Sep 17 00:00:00 2001 From: Luan Taraschi <130802253+luantaraschi@users.noreply.github.com> Date: Sat, 8 Aug 2026 16:27:36 -0300 Subject: [PATCH] fix: Fix crash on a `null` color in attribute output (#32784) --- lib/controller.ts | 5 ++++- test/controller.test.ts | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/controller.ts b/lib/controller.ts index deb216015..bd0066f61 100644 --- a/lib/controller.ts +++ b/lib/controller.ts @@ -465,7 +465,10 @@ export class Controller { let message: string | undefined; // Special cases - if (key === "color" && utils.objectHasProperties(subPayload, ["r", "g", "b"])) { + // `objectHasProperties` indexes its argument, so it has to be given an object. + // The null check three lines below is too late: `color` is nullable like any + // other attribute, and a null one reaches here before that branch runs. + if (key === "color" && subPayload != null && utils.objectHasProperties(subPayload, ["r", "g", "b"])) { subPayload = [subPayload.r, subPayload.g, subPayload.b]; } diff --git a/test/controller.test.ts b/test/controller.test.ts index de43d0e24..318784ebe 100644 --- a/test/controller.test.ts +++ b/test/controller.test.ts @@ -1061,6 +1061,17 @@ describe("Controller", () => { ); }); + it("Publish entity state attribute output with a null color", async () => { + await controller.start(); + settings.set(["advanced", "output"], "attribute_and_json"); + mockMQTTPublishAsync.mockClear(); + const device = getZ2MDevice("bulb"); + await controller.publishEntityState(device, {state: "ON", color: null}); + await flushPromises(); + expect(mockMQTTPublishAsync).toHaveBeenCalledWith("zigbee2mqtt/bulb/state", "ON", {qos: 0, retain: true}); + expect(mockMQTTPublishAsync).toHaveBeenCalledWith("zigbee2mqtt/bulb/color", "", {qos: 0, retain: true}); + }); + it("Publish entity state attribute_json output filtered", async () => { await controller.start(); settings.set(["advanced", "output"], "attribute_and_json");