Skip to content

fix: handle renamed "item" key in playlist tracks - #775

Open
maxmaxme wants to merge 1 commit into
joostlek:mainfrom
maxmaxme:fix/playlist-item-track-rename
Open

fix: handle renamed "item" key in playlist tracks#775
maxmaxme wants to merge 1 commit into
joostlek:mainfrom
maxmaxme:fix/playlist-item-track-rename

Conversation

@maxmaxme

Copy link
Copy Markdown

Spotify's Feb 2026 API migration renamed the playlist track wrapper from track to item and deprecated track. PlaylistTrack still expects track, so get_playlist/get_playlist_items now blow up on the new payload:

MissingField: Field "track" of type Item is missing in PlaylistTrack instance

This takes down the HA Spotify integration on the new payload — both when the coordinator polls a playing playlist and when browsing playlists in the media browser (home-assistant/core#165877).

Map item back to track in PlaylistTrack.__pre_deserialize__, same as Playlist already does for tracksitems. Old track payloads still work, so both shapes are fine during the deprecation window. Also made PlaylistTracks tolerate a missing items list (non-owned playlists return metadata only — same thing #767 was after).

Added fixtures for the new item-only shape and parametrized them into the existing playlist tests.

Fixes #774

Spotify's February 2026 Web API migration renamed the per-entry track
wrapper from "track" to "item" (tracks.track -> items.item) and marked
"track" deprecated. PlaylistTrack still required "track", so get_playlist
and get_playlist_items raised MissingField/InvalidFieldValue on the new
shape, which breaks the Home Assistant Spotify integration on playlist
playback.

Normalize the new "item" key back to "track" in PlaylistTrack's
__pre_deserialize__ hook -- same pattern already used by
Playlist.__pre_deserialize__ (tracks -> items) and
Album.__pre_deserialize__ (flattening tracks.items). The legacy "track"
key still passes through unchanged, so both shapes work during the
deprecation window. Also tolerate a missing "items" list, since
non-owned playlists now return only metadata.

Tests: new playlist_4.json and playlist_items_2.json fixtures in the
"item"-only shape, parametrized into the existing playlist tests.
@github-actions

Copy link
Copy Markdown

There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days. Thank you for your contributions.

@github-actions github-actions Bot added the stale There has not been activity on this issue or PR for quite some time. label Jun 30, 2026
@maxmaxme

Copy link
Copy Markdown
Author

The issue is still relevant

@github-actions github-actions Bot removed the stale There has not been activity on this issue or PR for quite some time. label Jul 1, 2026
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days. Thank you for your contributions.

@github-actions github-actions Bot added the stale There has not been activity on this issue or PR for quite some time. label Aug 1, 2026
@maxmaxme

maxmaxme commented Aug 1, 2026

Copy link
Copy Markdown
Author

The issue is still relevant

@github-actions github-actions Bot removed the stale There has not been activity on this issue or PR for quite some time. label Aug 2, 2026
@Masaslo

Masaslo commented Aug 10, 2026

Copy link
Copy Markdown

Thanks for picking this up — this is a real production issue. I hit it on Home Assistant 2026.8.x (Spotify integration fails with MissingField: Field "track" of type Item is missing in PlaylistTrack instanceInvalidFieldValue: Field "items" of type PlaylistTracks in Playlist has invalid value), and I'm running a local variant of this fix, verified against a real playlist payload (65 tracks, all in the new item shape). The itemtrack normalization works.

While testing I found three edge cases the current diff doesn't cover:

  1. item can be null (or absent) for region-restricted/unavailable content. With this patch that becomes track: None, and since track isn't optional, mashumaro raises InvalidFieldValue again (None is not Item). Making the field Annotated[Item, Discriminator(field="type", include_subtypes=True)] | None, or filtering such entries in PlaylistTracks.__pre_deserialize__, avoids the crash.
  2. Local entries may be sparse: local-file entries (is_local: true) can lack most fields, so they need to be filtered in PlaylistTracks.__pre_deserialize__ before per-item deserialization — item.get("is_local") (instead of item["is_local"]) also handles entries where the key is missing.
  3. Simplified playlists omit items entirely (also reported as spotifyaio 2.0.2: "Field items of type PlaylistTracks is missing" with current Spotify API home-assistant/core#167322): d["items"] raises KeyError; d.get("items") or [] covers it.

My hardened version (normalize itemtrack, drop non-dict / is_local / null-item entries, tolerate missing items) passes regression tests for old + new format, null/missing inner items, and absent items, against spotifyaio 2.0.2.

Happy to open a follow-up PR with the hardening + tests, or adjust this one — whatever you prefer. Thanks again for the fix.

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.

get_playlist fails on the new "item" wrapper (Feb 2026 API change)

2 participants