music-assistant-server

Branch:dev-lidarr-plugin

Commit Details

Fix a group member never re-joining after it drops off the network (#6062)

# What does this implement/fix?

A speaker that dropped off the network while playing in a sync group
never re-joined on its own: the automatic re-join was silently refused
by the grouping pipeline and gave up after a single attempt, 5 seconds
after the loss. The player then stayed idle (and the group's member list
could go stale) until the group members were edited manually.

A user debug log showed the re-join failing this way on every occurrence
("Player X can not be grouped with Y"), even when the rest of the group
was healthy and playing.

- Re-join through the group leader's own `set_members` instead of the
user-facing grouping pipeline, whose compatibility gate reflects
grouping state that is in flux right after a stream loss and can
silently refuse an internal re-join
- Retry with a longer backoff ladder (5s up to 2 minutes) instead of a
single attempt after 5 seconds; every attempt still re-validates that
the group is playing and the player wasn't repurposed meanwhile
- Drop a member that lost its stream from its native sync leader
directly (extending what the static-member path already did), instead of
the group-level ungroup path that could remove the member from its sync
group over one dead transport - the wrong member count from the report

**Related issue (if applicable):**

- user report with debug log (no issue link)

## Types of changes

- [x] Bugfix (non-breaking change which fixes an issue) — `bugfix`
- [ ] New feature (non-breaking change which adds functionality) —
`new-feature`
- [ ] Enhancement to an existing feature — `enhancement`
- [ ] New music/player/metadata/plugin provider — `new-provider`
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected) — `breaking-change`
- [ ] Refactor (no behaviour change) — `refactor`
- [ ] Documentation only — `documentation`
- [ ] Maintenance / chore — `maintenance`
- [ ] CI / workflow change — `ci`
- [ ] Dependencies bump — `dependencies`

## Checklist

- [x] The code change is tested and works locally.
- [x] `pre-commit run --all-files` passes.
- [x] `pytest` passes, and tests have been added/updated under `tests/`
where applicable.
- [ ] For changes to shared models, the companion PR in
`music-assistant/models` is linked.
- [ ] For changes affecting the UI, the companion PR in
`music-assistant/frontend` is linked.
- [x] I have read and complied with the project's [AI
Policy](https://github.com/music-assistant/.github/blob/main/AI_POLICY.md)
for any AI-assisted contributions.
- [ ] I have [raised a PR against the documentation
repository](https://github.com/music-assistant/music-assistant.io/blob/main/CONTRIBUTING.md)
targeting the main or beta branch as appropriate.
Forgejo

Author

Marcel van der Veldt<[email protected]>
August 27, 2026 at 06:43 PM UTC

Committer

Marcel van der Veldt<[email protected]>
August 29, 2026 at 12:28 AM UTC
71additions
46deletions
9files changed

Parent commits

Changes

9 files
+71-46

Changed Files (9)

music_assistant/controllers/players/
music_assistant/providers/airplay/
tests/controllers/players/
tests/providers/airplay/
music_assistant/controllers/players/controller.py
music_assistant/providers/airplay/constants.py
music_assistant/providers/airplay/player.py
+17-7
music_assistant/providers/airplay/sendspin_bridge.py
music_assistant/providers/airplay/stream.py
+8-10
tests/controllers/players/test_player_controller.py
tests/providers/airplay/test_player.py
+34-29
tests/providers/airplay/test_protocol_crash.py
+3
tests/providers/airplay/test_stream.py
+9