Skip to content

Workaround for "Youtube Music playlist stalls on uploaded music" music-assistant/support#4469#3156

Draft
whitty wants to merge 2 commits intomusic-assistant:devfrom
whitty:bugfix/MPRE_stall
Draft

Workaround for "Youtube Music playlist stalls on uploaded music" music-assistant/support#4469#3156
whitty wants to merge 2 commits intomusic-assistant:devfrom
whitty:bugfix/MPRE_stall

Conversation

@whitty
Copy link
Copy Markdown

@whitty whitty commented Feb 13, 2026

This is a workaround for the "stalling" aspect of music-assistant/support#4469

MA tries to resolve albums providing the prov_album_id of the form FEmusic_library_privately_owned_release_detailb_po_<probably private_letters_and_numbers_id> which triggers an exception in ytmusic.get_album() as it checks that the ID .startswith('MPRE').

The handling of the exception seems to lead to playback stalling in this case. Catching and returning None (presumably like "not found") instead leads to a warning as follows, but playback doesn't stall.

2026-02-13 23:05:25.159 WARNING (MainThread) [music_assistant.music.track] Unable to fetch album details for ytmusic--xxxxxxx://track/JB2LoK_zfD4 - album://FEmusic_library_privately_owned_release_detailb_po_xxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx not found on provider ytmusic--xxxxxxx

This may not resolve the base issues:

  1. Why do we have a providerID for the album that cannot be looked up - has the wrong field been stored somewhere?
  2. Why does reloading MA often allow that album to be played successfully (though I don't see calls to get_album() in that case)

Approach:

I preferred to catch the exception rather than check the prefix, in case ytmusicapi resolves the issue and allows non MPRE prefixes in the future.

Since the Exception is a generic UserError type I specifically check the message and propagate any other exceptions..


Additionally I removed a duplicate lookup rather than expand the try block further.

@whitty whitty changed the title Workaround for "Youtube Music playlist stalls on uploaded music" #4469 Workaround for "Youtube Music playlist stalls on uploaded music" music-assistant/support#4469 Feb 13, 2026
@MarvinSchenkel
Copy link
Copy Markdown
Contributor

I would like to solve the root of the issue rather than implementing an 'except workaround'. Can you let me know what the album id is of your custom uploaded track that is triggering the issue? That might shed some light on this case.

except ytmusicapi.exceptions.YTMusicUserError as e:
if prov_album_id is not None and "must start with MPRE" in str(e):
logging.getLogger("music_assistant").getChild("YouTube Music").debug("ytmusicapi refused to handle prov_album_id: '%s'", prov_album_id)
return None
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note None is not a normal return path for ytm.get_album() there is no obvious "not-found" result

@whitty
Copy link
Copy Markdown
Author

whitty commented Feb 13, 2026

I would like to solve the root of the issue rather than implementing an 'except workaround'.

Understood. As I've pointed out the None return isn't the same as a "not found"

Can you let me know what the album id is of your custom uploaded track that is triggering the issue?

Can you explain exactly what information you are after?

As described the prov_album_id is a string of the form 'FEmusic_library_privately_owned_release_detailb_po_CP39qciXhNa_LxIUaG90dGVzdCAxMDAgdm9sdW1lIDgaCHRyaXBsZSBqIgNncG0' - I do not know if that is the album ID you are after - I did mention it in the PR description.

I do not know where this value came from - presumably from a query of the youtube api elsewhere and/or stored by MA itself from some source.

@MarvinSchenkel
Copy link
Copy Markdown
Contributor

That's exactly the info I was after. It looks like YTM internally stores this value as the album id for a track that was manually uploaded. Now of course we cannot link this to any album out there, which ultimately causes this error.

My suggestion is to prevent this value from ever creeping into MA. So instead of failing on a invalid album id in the helpers.py, we could just simply extend this check by checking if the album id is a valid id (e.g. and track_obj["album"]["id"].startswith("MPRE")). This will only add the Album to the track if the id is valid, preventing your album id from ever being synced to MA in the first place.

Copy link
Copy Markdown
Contributor

@MarvinSchenkel MarvinSchenkel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please have a look at my suggestion and mark this PR 'Ready for review' again once you have made the changes.

@MarvinSchenkel MarvinSchenkel marked this pull request as draft February 16, 2026 08:47
@OzGav
Copy link
Copy Markdown
Contributor

OzGav commented Mar 12, 2026

@whitty any progress on this? Would be good to get it into 2.8

@whitty
Copy link
Copy Markdown
Author

whitty commented Mar 19, 2026

That's exactly the info I was after. It looks like YTM internally stores this value as the album id for a track that was manually uploaded. Now of course we cannot link this to any album out there, which ultimately causes this error.

My suggestion is to prevent this value from ever creeping into MA. So instead of failing on a invalid album id in the helpers.py, we could just simply extend this check by checking if the album id is a valid id (e.g. and track_obj["album"]["id"].startswith("MPRE")). This will only add the Album to the track if the id is valid, preventing your album id from ever being synced to MA in the first place.

Sorry - I've been busy and not gotten back to this. I haven't had a chance to play around here.

I'm trying to parse your suggestion, and also clarify the behaviour I see (before attempting the change).

I know these are true:

  1. There's nothing inherently "wrong" with those IDs "in general" because from MA's perspective the tracks are still organised correctly into albums - ie they still have identity value, even if some metadata isn't available. MA correctly shows the album name (possibly the album Art, but that may be embedded in the track).
  2. Playback can continue without the album request that failed in the original stack-trace (player-queues -> music -> media/tracks -> media/albums)
    as described in this update - once the fail is "cached" (after a restart) it doesn't trigger the fail and playback seems normal.

This will only add the Album to the track if the id is valid,

My concern with this, is that it might "throw out the baby with the bathwater". Would that change leave the track "orphaned" in MA - just a track, but not on an album?

Is track.album = self._get_item_mapping(MediaType.ALBUM, album["id"], album["name"]) presumably is why we have at least the album name attached?

What I can't tell from the stack-traces is what information is being fetched, but I'd prefer to keep the album for its "Identity value", just return any metadata queries as if there was no data attached to that album. Not knowing the structure of how MA manages things I might be saying the wrong thing. I know my change doesn't really do that, but it kind of does by effect. I suspect there's a point in the middle where this could be managed more cleanly.

Trying to look a little deeper:

https://github.com/music-assistant/server/blob/fdf1ad5e6ad69dfbb8361cc753cc1e21bd3a05d0/music_assistant/controllers/media/tracks.py#L133C1-L136C18

            elif isinstance(track.album, ItemMapping) or (track.album and not track.album.image):
                track.album = await self.mass.music.albums.get(
                    track.album.item_id, track.album.provider, recursive=False
                )

This is replacing track.album - either if its an ItemMapping, or if it doesn't have an .image. Is ItemMapping just a stub for later resolving?

Did we have enough information in track_obj["album"] in ? do we need to create a mapping (assuming that's a deferred lookup)? Is there another object that can be inserted other than a mapping - this code from above (track.album and not track.album.image) suggests there is an alternative to an ItemMapping there (sorry for the silly questions I C++ by day, so I find it hard when I don't know what sort of object I'm pointing at).

I will instrument the code you have mentioned, then try preventing the mapping from being created, though I'm worried about the side-effects and whether @cache will make it hard to be sure what the actual result is.

@whitty whitty force-pushed the bugfix/MPRE_stall branch from 117afe5 to 9d3b9e0 Compare March 19, 2026 22:19
@whitty
Copy link
Copy Markdown
Author

whitty commented Mar 19, 2026

OK - I've looked deeper and I'm happier with this, though I still class it as "workaround" at this point - it prevents the playback errors.

Digging through ytmusicapi ytm.get_library_upload_album() is the correct API for fetching uploaded albums with the given prefix.

This seems to resolve an OK Album object. However there are some rough edges. The track-list doesn't seem to resolve properly though its in the returned data.

Is there a place to put test-data - eg unittests for _parse_album() - where I could store returned data for reference? Its 90% the same in shape to a regular album return, with a few possible rough edges that might be causing the failure to cross-link with tracks.

@whitty whitty marked this pull request as ready for review March 19, 2026 22:27
@whitty whitty force-pushed the bugfix/MPRE_stall branch from 9d3b9e0 to 14694b2 Compare March 20, 2026 08:23
As per the API source ytm.get_library_upload_album() is the correct
API for fetching uploaded albums:

https://github.com/sigma67/ytmusicapi/blob/a8a120f37c5363ffb4d36d226c1afb2051bd4d79/ytmusicapi/mixins/uploads.py#L197

The result seems mostly compatible, except for the "playlist patch" a
few lines below, so just make that permissive.
@whitty whitty force-pushed the bugfix/MPRE_stall branch from 14694b2 to 7aa54b9 Compare March 20, 2026 08:25
@MarvinSchenkel
Copy link
Copy Markdown
Contributor

Yep there is a tests folder with tests. A few providers have already set up tests for this, you can just follow their pattern to setup some tests for album parsing in YTM :)

@OzGav OzGav added this to the 2.9.0 milestone Mar 25, 2026
@MarvinSchenkel
Copy link
Copy Markdown
Contributor

Marking this PR as draft so we can keep track of which PRs needs our attention. Please mark as 'Ready for review' when you want us to have another look 🙏 .

@MarvinSchenkel MarvinSchenkel marked this pull request as draft March 31, 2026 12:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants