Fix Sonos group regroup race when entity is not yet registered#169445
Merged
Fix Sonos group regroup race when entity is not yet registered#169445
Conversation
A polling-driven update_groups() can run before the media_player entity has been registered. async_get_entity_id then returns None, which was appended into sonos_group_entities as [None]. On subsequent zone group events the early-return condition (which checks `and self.sonos_group_entities`) treated [None] as truthy and skipped re-computing, leaving the bad state permanently. This race became deterministic on Python 3.14.3 due to the asyncio executor scheduling change (cpython#142358), causing three sonos tests to be skipped in #169046. Treat a missing entity_id the same as a missing speaker: mark as "members missing" and return so the next event retries. Also wait for background tasks after reload in test_subscription_repair_issues so the v2 async_subscription_failed fires before the test calls the success callback.
Contributor
|
Hey there @jjlawren, @PeteRager, mind taking a look at this pull request as it has been labeled with an integration ( Code owner commandsCode owners of
|
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a Sonos regroup race where sonos_group_entities could incorrectly contain None when a topology update runs before the media_player entity is registered, and re-enables the previously skipped tests that exposed the issue on Python 3.14.3+.
Changes:
- Prevent
Nonefrom being added tosonos_group_entitiesby treating a missingentity_idas a missing group member and retrying later. - Re-enable three Sonos tests that were skipped due to Python 3.14.3 asyncio scheduling behavior.
- Stabilize
test_subscription_repair_issuesby waiting for background tasks after reload and after invoking the subscription callback.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
homeassistant/components/sonos/speaker.py |
Avoids persisting invalid group member entity IDs during regroup when entity registration hasn’t completed yet. |
tests/components/sonos/test_speaker.py |
Re-enables the ZGS grouping test previously skipped for Python 3.14.3 asyncio behavior. |
tests/components/sonos/test_media_player.py |
Re-enables the basic entity snapshot test previously skipped for Python 3.14.3 asyncio behavior. |
tests/components/sonos/test_repairs.py |
Re-enables repairs test and ensures async background work completes before assertions. |
frenck
approved these changes
Apr 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Breaking change
Proposed change
Re-enables the three sonos tests skipped in #169046 and fixes the underlying race they exposed.
SonosSpeaker.setup()schedules a polling-drivenupdate_groups()coroutine and the platform-creatingasync_setup()task at the same time. The polling task calls_async_regroup, which looks up themedia_playerentity ID viaasync_get_entity_id. If platform setup has not yet registered the entity, that returnsNone, andNonewas being appended directly tosonos_group_entitiesas[None].Worse, a later early-return condition (
group == [self.soco.uid] and self.sonos_group == [self] and self.sonos_group_entities) treated[None]as truthy and skipped re-computing, so subsequent zone group events could not repair the state. The state then surfaced asgroup_members: [None]on the entity.On Python 3.14.3 the asyncio executor scheduling change (cpython#142358) made
await hass.async_add_executor_job(...)no longer yield to the loop, so the polling regroup deterministically wins the race against entity registration. This is why the three tests started failing.Fix: in
_async_regroup, treat a missingentity_idthe same as a missing speaker — mark the uid as missing and return, so the next event retries. This avoids ever storingNoneinsonos_group_entities.Also,
test_subscription_repair_issuesneedswait_background_tasks=Trueafter reload so the newasync_subscription_failedfires before the test invokes the success callback (otherwise it can re-create the issue after the deletion and fail the assertion).Type of change
Additional information
Checklist
ruff format homeassistant tests)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest.requirements_all.txt.Updated by running
python3 -m script.gen_requirements_all.To help with the load of incoming pull requests: