/
/
# What does this implement/fix? When a music provider hands back an unexpected response for a single item, it usually fails with a plain Python error rather than one of our own error types. The sync loops only caught our own errors, so instead of skipping that one album or track, the whole library sync for that media type stopped there and did not resume until the next scheduled run. This has been showing up per provider for a while now (#5629 for YouTube Music, #5738 for Soundcloud, #4089 for Apple Music), fixed one provider at a time. This catches it in the shared sync loop so it applies to every provider. Skipping an item has a second effect that was already there for our own errors: a skipped item looks exactly like one that was removed on the provider side, so the cleanup step that follows could unmark it as being in your library, or delete it outright for local/server providers. Cleanup is now held back whenever a run did not complete, the same way the filesystem provider already does it. **Related issue (if applicable):** - n/a ## 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` ## Changes - A failing item is skipped and the sync carries on, instead of stopping the whole media type. - Library cleanup is held back for any run that could not sync every item, so nothing that is still on the provider gets removed. This now also covers items that fail with one of our own errors, which were previously skipped but still treated as removed. - A held-back run keeps the previous item list, so deletions it could not process are still picked up by the next clean run. - Failing to import an album's tracks, a playlist's tracks or a podcast's episodes no longer holds back cleanup, since the item itself synced fine. - Unexpected errors are logged apart from expected ones, with a traceback on debug, and per-item logging is capped so one bad provider cannot flood the log. - The nine near-identical error handlers in the sync loops now share one helper. ## 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.