From: Marcel van der Veldt Date: Mon, 23 Feb 2026 01:03:33 +0000 (+0100) Subject: Fix player config not fully persisting X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=35960c9e8bb8c9e35dcaa8b80e62a4f2fadc404f;p=music-assistant-server.git Fix player config not fully persisting --- diff --git a/music_assistant/controllers/config.py b/music_assistant/controllers/config.py index a9362178..016eae6c 100644 --- a/music_assistant/controllers/config.py +++ b/music_assistant/controllers/config.py @@ -803,20 +803,33 @@ class ConfigController: """Save/update PlayerConfig.""" values = await self._update_output_protocol_config(values) config = await self.get_player_config(player_id) - old_config = deepcopy(config) changed_keys = config.update(values) if not changed_keys: # no changes return config # store updated config first (to prevent issues with enabling/disabling players) conf_key = f"{CONF_PLAYERS}/{player_id}" - self.set(conf_key, config.to_raw()) + # Get existing raw config to preserve values that don't have config entries. + # This can happen when config entries are dynamic (e.g., protocol settings depend on + # player.available and linked protocols). If save_player_config is called before + # the player is fully available, those entries won't exist and their stored values + # would be lost without this preservation. + existing_raw = self.get(conf_key) or {} + existing_values = existing_raw.get("values", {}) + new_raw = config.to_raw() + new_values = new_raw.get("values", {}) + # Preserve values from storage that don't have config entries in current context + for key, value in existing_values.items(): + if key not in new_values: + new_values[key] = value + new_raw["values"] = new_values + self.set(conf_key, new_raw) try: # validate/handle the update in the player manager await self.mass.players.on_player_config_change(config, changed_keys) except Exception: - # rollback on error - self.set(conf_key, old_config.to_raw()) + # rollback on error - use existing_raw to preserve all values + self.set(conf_key, existing_raw) raise # send config updated event self.mass.signal_event(