From f473c1574cc30f4be3f87fa79fe40cc892d1040f Mon Sep 17 00:00:00 2001 From: Nils Ove Erstad Date: Sun, 5 Apr 2026 13:10:20 +0200 Subject: [PATCH] Fix missing color_mode initialization in MQTT JSON light schema Initialize `_attr_color_mode` to `ColorMode.UNKNOWN` before the color mode branching logic in `_setup_from_config`, matching the pattern already used in `schema_template.py` (added in #162715). Without this, `_attr_color_mode` can remain `None` (the new default from #162715) in edge cases during entity (re)setup, causing "does not report a color mode" errors when the light is on. Also removes the unused `_fixed_color_mode` class variable. --- .../components/mqtt/light/schema_json.py | 2 +- tests/components/mqtt/test_light_json.py | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/mqtt/light/schema_json.py b/homeassistant/components/mqtt/light/schema_json.py index 6b1db79e269fbc..b388cdebb6516e 100644 --- a/homeassistant/components/mqtt/light/schema_json.py +++ b/homeassistant/components/mqtt/light/schema_json.py @@ -146,7 +146,6 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity): _entity_id_format = ENTITY_ID_FORMAT _attributes_extra_blocked = MQTT_LIGHT_ATTRIBUTES_BLOCKED - _fixed_color_mode: ColorMode | str | None = None _flash_times: dict[str, int | None] _topic: dict[str, str | None] _optimistic: bool @@ -190,6 +189,7 @@ def _setup_from_config(self, config: ConfigType) -> None: self._attr_supported_features |= ( config[CONF_TRANSITION] and LightEntityFeature.TRANSITION ) + self._attr_color_mode = ColorMode.UNKNOWN if supported_color_modes := self._config.get(CONF_SUPPORTED_COLOR_MODES): self._attr_supported_color_modes = supported_color_modes if self.supported_color_modes and len(self.supported_color_modes) == 1: diff --git a/tests/components/mqtt/test_light_json.py b/tests/components/mqtt/test_light_json.py index 570609a86c0e26..6ea2cb3a9d4e8f 100644 --- a/tests/components/mqtt/test_light_json.py +++ b/tests/components/mqtt/test_light_json.py @@ -513,6 +513,58 @@ async def test_brightness_only( assert state.state == STATE_OFF +@pytest.mark.parametrize( + "hass_config", + [ + { + mqtt.DOMAIN: { + light.DOMAIN: { + "schema": "json", + "name": "test", + "state_topic": "test_light", + "command_topic": "test_light/set", + "supported_color_modes": ["brightness"], + } + } + }, + { + mqtt.DOMAIN: { + light.DOMAIN: { + "schema": "json", + "name": "test", + "state_topic": "test_light", + "command_topic": "test_light/set", + "supported_color_modes": ["color_temp"], + } + } + }, + ], +) +async def test_single_color_mode_turn_on( + hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator +) -> None: + """Test turning on a single color mode light does not raise. + + Regression test: PR #162715 changed _attr_color_mode default to None + and added a strict check. The JSON schema must initialize color_mode + during setup so that turn_on does not raise "does not report a color mode". + """ + mqtt_mock = await mqtt_mock_entry() + + state = hass.states.get("light.test") + assert state.state == STATE_UNKNOWN + + # This should not raise "does not report a color mode" + await common.async_turn_on(hass, "light.test") + mqtt_mock.async_publish.assert_called_once_with( + "test_light/set", '{"state":"ON"}', 0, False + ) + + async_fire_mqtt_message(hass, "test_light", '{"state":"ON", "brightness": 50}') + state = hass.states.get("light.test") + assert state.state == STATE_ON + + @pytest.mark.parametrize( "hass_config", [