Specific library throwing an error on sync: ParseError: not well-formed (invalid token)
BackedUpBooty opened this issue · comments
Confirmation
- I have read the README.md on the project homepage
- I have checked if identical issue already exists
- I have tried downgrading to find version that can be used as a workaround
The problem
I have 3 plex libraries connected to plextraktsync as shown below when running the plextraktsync info
command:
Plex Server version: 1.40.0.7775-456fbaf97, updated at: 2024-02-03 11:23:10
Enabled 3 libraries in Plex Server:
- 1: Movies
- 2: TV Shows
- 8: Music
When running the sync
command, Movies
and TV Shows
are processed, but it then throws an error:
Processing Movies 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 311/311 [ 0:00:05 < 0:00:00 , 53 it/s ]
INFO Movies processed in 8.1 seconds
INFO Preload shows data
Processing TV Shows 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 247/247 [ 0:00:01 < 0:00:00 , 233 it/s ]
INFO TV Shows processed in 1.8 seconds
INFO Preloaded shows data (247 shows)
ERROR not well-formed (invalid token): line 152, column 1262
which then shows the following traceback (link) seemingly having an issue with the TV Show library/episodes etc. https://pastebin.com/9cyjWZZQ
If I add TV Shows
to excluded-libraries:
in the config then the sync works as expected with just Movies
.
Using the inspect
command on a specific TV show returns a valid and expected response.
Steps to reproduce the behavior
- Have PlexTraktSync working normally for a couple of months with
TV Shows
andMovies
libraries being sync'd - Update containers for both plextraktsync and plex as updates are released/confirmed
- Bug happens....
Error trace / logs
ERROR not well-formed (invalid token): line 152, column 1262
╭─────────────────────────────────────────────────────── Traceback (most recent call last) ────────────────────────────────────────────────────────╮
│ /app/plextraktsync/cli.py:26 in wrap │
│ │
│ 23 │ │ │ cmd = getattr(module, name) │
│ 24 │ │ │ │
│ 25 │ │ │ try: │
│ ❱ 26 │ │ │ │ cmd(*args, **kwargs) │
│ 27 │ │ │ except EOFError as e: │
│ 28 │ │ │ │ raise ClickException(f"Program requested terminal, No terminal is │
│ connected: {e}") │
│ 29 │ │ │ except ClickException as e: │
│ │
│ /app/plextraktsync/commands/sync.py:68 in sync │
│ │
│ 65 │ │ │ w.print_plan(print=logger.info) │
│ 66 │ │ if dry_run: │
│ 67 │ │ │ logger.info("Enabled dry-run mode: not making actual changes") │
│ ❱ 68 │ │ runner.sync(walker=w, dry_run=config.dry_run) │
│ 69 │
│ │
│ /app/plextraktsync/sync.py:78 in sync │
│ │
│ 75 │ │ │ │
│ 76 │ │ │ shows = set() │
│ 77 │ │ │ episode_trakt_ids = set() │
│ ❱ 78 │ │ │ for episode in walker.find_episodes(): │
│ 79 │ │ │ │ self.sync_collection(episode, dry_run=dry_run) │
│ 80 │ │ │ │ self.sync_ratings(episode, dry_run=dry_run) │
│ 81 │ │ │ │ self.sync_watched(episode, dry_run=dry_run) │
│ │
│ /app/plextraktsync/plan/Walker.py:115 in find_episodes │
│ │
│ 112 │ │ self.logger.info(f"Preloaded shows data ({len(plex_shows)} shows)") │
│ 113 │ │ │
│ 114 │ │ show_cache = {} │
│ ❱ 115 │ │ for ep in self.episodes_from_sections(self.plan.show_sections): │
│ 116 │ │ │ show_id = ep.show_id │
│ 117 │ │ │ ep.show = plex_shows[show_id] │
│ 118 │ │ │ show = show_cache[show_id] if show_id in show_cache else None │
│ │
│ /app/plextraktsync/plan/Walker.py:164 in episodes_from_sections │
│ │
│ 161 │ │ │ │ │ section.pager("episode"), │
│ 162 │ │ │ │ │ desc=f"Processing {section.title_link}", │
│ 163 │ │ │ │ ) │
│ ❱ 164 │ │ │ │ yield from it │
│ 165 │ │
│ 166 │ def media_from_items(self, libtype: str, items: list) -> Generator[PlexLibraryItem, │
│ Any, None]: │
│ 167 │ │ it = self.progressbar(items, desc=f"Processing {libtype}s") │
│ │
│ /app/plextraktsync/plan/Walker.py:184 in progressbar │
│ │
│ 181 │ │ if self._progressbar: │
│ 182 │ │ │ pb = self._progressbar(iterable, **kwargs) │
│ 183 │ │ │ with pb as it: │
│ ❱ 184 │ │ │ │ yield from it │
│ 185 │ │ else: │
│ 186 │ │ │ yield from iterable │
│ 187 │
│ │
│ /app/plextraktsync/rich/RichProgressBar.py:22 in __next__ │
│ │
│ 19 │ │ return self │
│ 20 │ │
│ 21 │ def __next__(self): │
│ ❱ 22 │ │ res = self.iterable_next() │
│ 23 │ │ self.update() │
│ 24 │ │ return res │
│ 25 │
│ │
│ /app/plextraktsync/plex/PlexSectionPager.py:40 in __iter__ │
│ │
│ 37 │ │ size = X_PLEX_CONTAINER_SIZE │
│ 38 │ │ │
│ 39 │ │ while True: │
│ ❱ 40 │ │ │ items = self.fetch_items(start=start, size=size) │
│ 41 │ │ │ │
│ 42 │ │ │ if not len(items): │
│ 43 │ │ │ │ break │
│ │
│ /app/plextraktsync/decorators/retry.py:27 in wrapper │
│ │
│ 24 │ │ │ count = 0 │
│ 25 │ │ │ while True: │
│ 26 │ │ │ │ try: │
│ ❱ 27 │ │ │ │ │ return fn(*args, **kwargs) │
│ 28 │ │ │ │ except ( │
│ 29 │ │ │ │ │ │ BadRequest, │
│ 30 │ │ │ │ │ │ BadResponseException, │
│ │
│ /app/plextraktsync/plex/PlexSectionPager.py:30 in fetch_items │
│ │
│ 27 │ │
│ 28 │ @retry() │
│ 29 │ def fetch_items(self, start: int, size: int): │
│ ❱ 30 │ │ return self.section.search(libtype=self.libtype, container_start=start, │
│ container_size=size, maxresults=size) │
│ 31 │ │
│ 32 │ def __iter__(self): │
│ 33 │ │ from plexapi import X_PLEX_CONTAINER_SIZE │
│ │
│ /usr/local/lib/python3.12/site-packages/plexapi/library.py:1517 in search │
│ │
│ 1514 │ │ """ │
│ 1515 │ │ key, kwargs = self._buildSearchKey( │
│ 1516 │ │ │ title=title, sort=sort, libtype=libtype, limit=limit, filters=filters, │
│ returnKwargs=True, **kwargs) │
│ ❱ 1517 │ │ return self.fetchItems( │
│ 1518 │ │ │ key, container_start=container_start, container_size=container_size, │
│ maxresults=maxresults, **kwargs) │
│ 1519 │ │
│ 1520 │ def _locations(self): │
│ │
│ /usr/local/lib/python3.12/site-packages/plexapi/base.py:255 in fetchItems │
│ │
│ 252 │ │ │ headers['X-Plex-Container-Start'] = str(container_start) │
│ 253 │ │ │ headers['X-Plex-Container-Size'] = str(container_size) │
│ 254 │ │ │ │
│ ❱ 255 │ │ │ data = self._server.query(ekey, headers=headers) │
│ 256 │ │ │ subresults = self.findItems(data, cls, ekey, **kwargs) │
│ 257 │ │ │ total_size = utils.cast(int, data.attrib.get('totalSize') or │
│ data.attrib.get('size')) or len(subresults) │
│ 258 │
│ │
│ /usr/local/lib/python3.12/site-packages/plexapi/server.py:771 in query │
│ │
│ 768 │ │ │ else: │
│ 769 │ │ │ │ raise BadRequest(message) │
│ 770 │ │ data = response.text.encode('utf8') │
│ ❱ 771 │ │ return ElementTree.fromstring(data) if data.strip() else None │
│ 772 │ │
│ 773 │ def search(self, query, mediatype=None, limit=None, sectionId=None): │
│ 774 │ │ """ Returns a list of media items or filter categories from the resulting │
│ │
│ /usr/local/lib/python3.12/xml/etree/ElementTree.py:1323 in XML │
│ │
│ 1320 │ """ │
│ 1321 │ if not parser: │
│ 1322 │ │ parser = XMLParser(target=TreeBuilder()) │
│ ❱ 1323 │ parser.feed(text) │
│ 1324 │ return parser.close() │
│ 1325 │
│ 1326 │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ ▲ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
ParseError: not well-formed (invalid token): line 152, column 1262
Error: Error running sync command: not well-formed (invalid token): line 152, column 1262
Expected behavior
Movies and TV shows are sync'd which then moves on to watchlist etc. and the command is completed without error
Inspect of problematic items
inspect
commands on TV shows return results (the following is one of the latest shows to be watched by multiple users) :
$ docker-compose run --rm plextraktsync inspect 38110
PlexTraktSync [0.28.15]
INFO Connecting with url: https://[redacted], timeout 30 seconds
Inspecting <PlexId:38110>: <tmdb:60622:Show:38110:Fargo>
--- Plex
Plex Web URL: https://app.plex.tv/desktop/#!/server/a1100675d843bd0ab696c3451acf8232d0d9a46f/details?key=/library/metadata/38110
Discover URL: https://app.plex.tv/desktop/#!/provider/tv.plex.provider.discover/details?key=/library/metadata/5d9c0838ffd9ef001e98fd77
Title: Fargo
Media.Type: 'show'
Media.Guid: 'plex://show/5d9c0838ffd9ef001e98fd77'
Media.Guids: [<Guid:imdb://tt2802850>, <Guid:tmdb://60622>, <Guid:tvdb://269613>]
Guids:
Guid: <PlexGuid:tmdb://60622>, Id: 60622, Provider: 'tmdb'
Guid: <PlexGuid:tvdb://269613>, Id: 269613, Provider: 'tvdb'
Guid: <PlexGuid:imdb://tt2802850>, Id: tt2802850, Provider: 'imdb'
Metadata: {'collected_at': '2023-12-25:T06:04:39.000Z', 'media_type': 'digital'}
Played on Plex: False
Plex play history:
- 2024-02-01 23:30:14 <EpisodeHistory:38112:Fargo-s05e01>: by [redacted] on iPad with iOS
- 2024-01-31 23:08:58 <EpisodeHistory:38130:Fargo-s04e11>: by [redacted] on iPad with iOS
- 2024-01-30 23:20:16 <EpisodeHistory:38129:Fargo-s04e10>: by [redacted] on iPad with iOS
- 2024-01-28 22:57:46 <EpisodeHistory:38128:Fargo-s04e09>: by [redacted] on iPad with iOS
- 2024-01-28 09:14:44 <EpisodeHistory:38117:Fargo-s04e01>: by [redacted] on AFTSSS with Android
- 2024-01-27 19:48:36 <EpisodeHistory:38127:Fargo-s04e08>: by [redacted] on iPad with iOS
- 2024-01-26 22:52:27 <EpisodeHistory:38125:Fargo-s04e06>: by [redacted] on iPhone with iOS
- 2024-01-26 19:58:35 <EpisodeHistory:38124:Fargo-s04e05>: by [redacted] on iPhone with iOS
- 2024-01-24 22:34:03 <EpisodeHistory:38123:Fargo-s04e04>: by [redacted] on iPad with iOS
- 2024-01-22 23:18:22 <EpisodeHistory:38121:Fargo-s04e03>: by [redacted] on iPad with iOS
- 2024-01-21 19:17:02 <EpisodeHistory:38119:Fargo-s04e02>: by [redacted] on iPad with iOS
- 2024-01-20 00:27:21 <EpisodeHistory:38117:Fargo-s04e01>: by [redacted] on iPad with iOS
- 2023-12-31 17:34:56 <EpisodeHistory:38166:Fargo-s05e07>: by [redacted] on LG OLED55C1PJB with webOS
- 2023-12-31 16:46:49 <EpisodeHistory:38122:Fargo-s05e06>: by [redacted] on LG OLED55C1PJB with webOS
- 2023-12-29 01:17:35 <EpisodeHistory:38120:Fargo-s05e05>: by [redacted] on LG OLED55C1PJB with webOS
- 2023-12-29 00:36:14 <EpisodeHistory:38118:Fargo-s05e04>: by [redacted] on LG OLED55C1PJB with webOS
- 2023-12-28 23:51:45 <EpisodeHistory:38115:Fargo-s05e03>: by [redacted] on LG OLED55C1PJB with webOS
- 2023-12-28 23:11:02 <EpisodeHistory:38114:Fargo-s05e02>: by [redacted] on LG OLED55C1PJB with webOS
- 2023-12-28 22:25:21 <EpisodeHistory:38112:Fargo-s05e01>: by [redacted] on LG OLED55C1PJB with webOS
--- Trakt
Trakt: https://trakt.tv/shows/fargo
Plex Rating: None
Trakt Rating: None
Workarounds
I'm not about any workarounds which may exist here. I have a task which runs the sync command once a night, the first one happened January 30th, v 28.12, I rolled back to 28.11 and 28.10, no change. Today I updated to latest (28.15) and the issue persists.
Install method
docker-compose
Config file contents
cache:
path: $[redacted]_CACHE_DIR/trakt_cache
excluded-libraries:
- Private
- Family Holidays
# - TV Shows
config:
dotenv_override: true
plex:
timeout: 30
logging:
append: true
# Whether to show timestamps in console messages
console_time: false
debug: false
filename: plextraktsync.log
filter:
# # Filter out all messages with level WARNING
# - level: WARNING
# # Filter out message with level WARNING and containing a text
# - level: WARNING
# message: "not found on Trakt"
# - message: "because provider local has no external Id"
# - message: "because provider none has no external Id"
# - message: "Retry using search for specific Plex Episode"
# settings for 'sync' command (default)
sync:
plex_to_trakt:
collection: true
ratings: true
watched_status: true
# If plex_to_trakt watchlist=false and trakt_to_plex watchlist=true
# the Plex watchlist will be overwritten by Trakt watchlist
watchlist: true
trakt_to_plex:
liked_lists: true
ratings: true
watched_status: true
# If trakt_to_plex watchlist=false and plex_to_trakt watchlist=true
# the Trakt watchlist will be overwritten by Plex watchlist
watchlist: true
# If you prefer to fetch trakt watchlist as a playlist instead of
# plex watchlist, toggle this to true (is read only if watchlist=true)
watchlist_as_playlist: false
# settings for 'watch' command
watch:
add_collection: false
remove_collection: false
# what video watched percentage (0 to 100) triggers the watched status
scrobble_threshold: 80
# true to scrobble only what's watched by you, false for all your PMS users
username_filter: true
xbmc-providers:
movies: imdb
shows: tmdb
# vim:ts=2:sw=2:et
Version
PlexTraktSync 0.28.15
Python Version
Python Version: 3.12.1 (main, Jan 27 2024, 06:36:14) [GCC 13.2.1 20231014]
Plex Server Version
Plex Server version: 1.40.0.7775-456fbaf97, updated at: 2024-02-03 11:23:10
Operating System and Version
Synology DSM
The issue seems to come very low level, from XML that Plex server returns. Unfortunately not much that can be done here. Did you check plex server logs? and plex forums? is plex server latest? was it updated recently?
how do you think item id=38110 is related to the problem?
enable debug log, and look what is the last plex URL requested, then user plex-api.sh script (from this repository) to download the XML. is that XML still not valid?
Thanks for the quick replies. I figured out it was a plex issue, not a plextraktsync issue. Some users hadn't told me, but it seems a few of them weren't seeing TV Shows in Home or 'Recommended' anymore, but because they could still browse through the 'Library' tab they'd not bothered to report it.
Something (not sure what) happened to the library settings for some users, I just recreated the library from the same media folder and now the sync is working.
Sorry for wasting your time, closing the issue.