I’m writing this post to share a bug I found with the metadata.provider.plex.tv metadata source. The bug involves a pretty bizarre and specific edge case where the user state gets returned incorrectly. I’ll try to break it down into its reproducing requirements below and provide an example offending request:
- Make a request to
metadata.provider.plex.tvfor the children of a show (/library/metadata/{ratingKey}/children) - The request must use the
includeUserStateparam - The request must use the
episodeOrderparam
And below is an example request:
https://metadata.provider.plex.tv/library/metadata/5e1622d34f2292003e91314a/children?includeUserState=1&episodeOrder=tvdbAiring
The combination of includeUserState=1 and episodeOrder=tvdbAiring breaks the user state data. Without an episode order, the user state is returned correctly (e.g. in viewedLeafCount). However, with episodeOrder included, the user state always returns incorrectly (e.g.viewedLeafCount is always 0).
Here’s a side-by-side comparison of the same example request as above with and without the episodeOrder param:
With episodeOrder
<MediaContainer librarySectionID="home" librarySectionTitle="Metadata" offset="0" totalSize="3" identifier="tv.plex.provider.metadata" size="3">
<Directory art="https://artworks.thetvdb.com/banners/v4/season/1971742/backgrounds/640194a576f32.jpg" banner="https://artworks.thetvdb.com/banners/v4/season/1971742/banners/64019535f16a9.jpg" guid="plex://season/61bc714e4fe00ccfae63bcf5" key="/library/metadata/61bc714e4fe00ccfae63bcf5/children" ratingKey="61bc714e4fe00ccfae63bcf5" type="season" thumb="https://artworks.thetvdb.com/banners/v4/season/1971742/posters/62113d7daa972.jpg" addedAt="1645142400" publicPagesURL="https://watch.plex.tv/show/severance/season/1" viewedLeafCount="0" title="Season 1" hasGenericTitle="1" parentSlug="severance" parentTitle="Severance" parentType="show" parentArt="https://image.tmdb.org/t/p/original/8MtMFngDWvIdRo34rz3ao0BGBAe.jpg" parentThumb="https://image.tmdb.org/t/p/original/pPHpeI2X1qEd1CS1SeyrdhZ4qnT.jpg" parentRatingKey="5e1622d34f2292003e91314a" parentGuid="plex://show/5e1622d34f2292003e91314a" parentKey="/library/metadata/5e1622d34f2292003e91314a" leafCount="9" index="1" contentRating="TV-MA" originallyAvailableAt="2022-02-18" year="2022">
...
</Directory>
...
</MediaContainer>
Without episodeOrder
<MediaContainer librarySectionID="home" librarySectionTitle="Metadata" offset="0" totalSize="3" identifier="tv.plex.provider.metadata" size="3">
<Directory art="http://assets.fanart.tv/fanart/tv/371980/seasonthumb/severance-640194737dcd7.jpg" banner="http://assets.fanart.tv/fanart/tv/371980/seasonbanner/severance-6401951cc0e73.jpg" guid="plex://season/5e1622d34f2292003e91314e" key="/library/metadata/5e1622d34f2292003e91314e/children" rating="9.7" ratingKey="5e1622d34f2292003e91314e" summary="At Lumon Industries, employees undergo "severance," a procedure dividing their work and personal memories. Mark, a grieving team leader, begins to uncover the dark secrets of the company, forcing him and his coworkers to confront questions of identity, free will, and corporate control." type="season" thumb="https://image.tmdb.org/t/p/original/lFf6LLrQjYldcZItzOkGmMMigP7.jpg" addedAt="1645056000" publicPagesURL="https://watch.plex.tv/show/severance/season/1" viewedLeafCount="9" title="Season 1" hasGenericTitle="1" parentSlug="severance" parentTitle="Severance" parentType="show" parentArt="https://image.tmdb.org/t/p/original/8MtMFngDWvIdRo34rz3ao0BGBAe.jpg" parentThumb="https://image.tmdb.org/t/p/original/pPHpeI2X1qEd1CS1SeyrdhZ4qnT.jpg" parentRatingKey="5e1622d34f2292003e91314a" parentGuid="plex://show/5e1622d34f2292003e91314a" parentKey="/library/metadata/5e1622d34f2292003e91314a" leafCount="9" index="1" contentRating="TV-MA" originallyAvailableAt="2022-02-17" year="2022" audienceRating="8.5" audienceRatingImage="rottentomatoes://image.rating.upright" ratingImage="rottentomatoes://image.rating.ripe">
...
</Directory>
...
</MediaContainer>
The difference to note is in the viewedLeafCount attribute. When episodeOrder is included, the viewedLeafCount is 0 instead of 9 (the correct value).
The issue extends even further because when requesting the user state for a specific season (instead of the children of a show), the user state is always returned incorrectly with viewedLeafCount as 0, regardless of the episodeOrder param. Here’s an example request:
https://metadata.provider.plex.tv/library/metadata/61bc714e4fe00ccfae63bcf5?includeUserState=1&episodeOrder=tvdbAiring
I’ll also note that this problem is exclusive to seasons. When requesting the user state of a show, an episode, or the children of a season, the user state is always returned correctly with viewedLeafCount or viewCount as the correct value.
The /library/metadata/{ratingKey}/userState endpoint for seasons is also unaffected by this bug. The user state bug only occurs when:
- Requesting a season, or the children of show
- Using the
includeUserStateparam - Using the
episodeOrderparam