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

  1. Remove the target entity_id from the group_members list before calling join
  2. Filter the list programmatically: members = [e for e in members if e != self.entity_id]
  3. 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

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


AI-assisted analysis of home-assistant/core@58a3fdb3ea (2026-08-14). Data as JSON: /api/errors/b8d2c6944f5de388. Report an issue: GitHub.