home-assistant/core · warning · ServiceValidationError
Cannot join player to itself
Error message
Cannot join player to itself
What it means
ServiceValidationError raised in async_join_players (the modern media_player.join service) when the caller includes the target entity itself in group_members. Grouping a player with itself is meaningless and would corrupt leader/follower topology, so the service call is rejected with a user-facing validation error.
Source
Thrown at homeassistant/components/bluesound/media_player.py:453
def shuffle(self) -> bool:
"""Return true if shuffle is active."""
shuffle = False
if self._status is not None:
shuffle = self._status.shuffle
return shuffle
@property
@override
def group_members(self) -> list[str] | None:
"""Get list of group members. Leader is always first."""
return self._group_members
@override
async def async_join_players(self, group_members: list[str]) -> None:
"""Join `group_members` as a player group with the current player."""
if self.entity_id in group_members:
raise ServiceValidationError("Cannot join player to itself")
entity_ids_with_sync_status = self._entity_ids_with_sync_status()
paired_players = []
for group_member in group_members:
sync_status = entity_ids_with_sync_status.get(group_member)
if sync_status is None:
continue
paired_player = id_to_paired_player(sync_status.id)
if paired_player:
paired_players.append(paired_player)
if paired_players:
await self._player.add_followers(paired_players)
@override
async def async_unjoin_player(self) -> None:
"""Remove this player from any group."""View on GitHub (pinned to 58a3fdb3ea)
Solutions
- Remove the target entity_id from the group_members list before calling join
- Filter the list programmatically: members = [e for e in members if e != self.entity_id]
- In UI actions, pick specific follower entities rather than 'all'
Example fix
# before
- action: media_player.join
target:
entity_id: media_player.living_room
data:
group_members: all
# after
- action: media_player.join
target:
entity_id: media_player.living_room
data:
group_members:
- media_player.kitchen
- media_player.bedroom Defensive patterns
Strategy: validation
Validate before calling
def members_valid(leader: str, group_members: list[str]) -> bool:
return leader not in group_members Try / catch
from homeassistant.exceptions import ServiceValidationError
try:
await entity.async_join_players(members)
except ServiceValidationError as err:
if "itself" in str(err):
members = [m for m in members if m != entity.entity_id]
await entity.async_join_players(members) Prevention
- Compute member lists with a filter that excludes the target entity_id
- Prefer explicit entity lists over 'all'/area expanders in join calls
When it happens
Trigger: Calling media_player.join with target = a bluesound entity and group_members containing that same entity_id (e.g. selecting 'all players' as both target and members, or passing entity_id: all).
Common situations: Automations or UI scripts that build the member list dynamically and accidentally include the leader; using area/all expanders on both sides of the service call.
Related errors
- Source {source} not found
- config_entry_not_loaded
- Failed to set temperature to {temperature}.
- Failed to set value.
- code_arm_required
AI-assisted analysis of home-assistant/core@58a3fdb3ea (2026-08-14).
Data as JSON: /api/errors/b8d2c6944f5de388.
Report an issue: GitHub.