Skip to content

[Bug] Plex item refresh never matches, so every subtitle triggers a full refresh of every Plex library #219

Closed

Description

@Svnow132

Summary

The Plex item lookup in mediaserver/plex.py uses a filter name plexapi always rejects, so it never finds the item and every subtitle falls back to a full refresh of every Plex library.

What actually happened?

The item lookup has never worked on my install. Since my oldest log (2026-08-12) there are 491 Triggered Plex full library refresh (3 sections) lines and 0 Triggered Plex item refresh lines. On busy days it was 54 full refreshes a day (2026-09-26), often seconds apart.

Where it fails

mediaserver/plex.py, _find_item_in_section (line 284 in 1.15.0):

results = section.search(filters={"Media__Part__file__startswith": mapped_dir})

I ran that exact call by hand inside the container against my Plex server. Every section raises:

BadRequest: Invalid filter field: Media__Part__file__startswith

The error comes from plexapi before anything is sent to Plex. LibrarySection._validateFilterField only accepts field names matching:

(?:([a-zA-Z]*)\.)?([a-zA-Z0-9]+)([!<>=&]*)

so a name containing __ can never pass. I also tried the other spellings I could think of, all rejected the same way:

episode.file__startswith  -> BadRequest: Invalid filter field
file__startswith          -> BadRequest: Invalid filter field
show.folder__startswith   -> BadRequest: Invalid filter field
file<<                    -> NotFound: Unknown filter field "file" for libtype "episode"

listFields() for both show and episode has no file or folder field at all, so I don't think any filter name can do a path lookup on the Plex side.

Why it is easy to miss

The BadRequest is caught at line 216 and only logged at DEBUG (Error searching Plex section ...). At INFO you only see the fallback, so it looks like Plex simply didn't have the item yet:

Item not found by path in Plex, falling back to library refresh: <path>
Triggered Plex full library refresh (3 sections)

A second, smaller problem in the fallback

refresh_library() calls section.update() on every section, ignoring the item_type hint. So a subtitle for a TV episode also rescans my two movie libraries. With the lookup broken, that happens on every download.

What should have happened?

Only the folder that got the new subtitle is scanned, in the matching library.

Plex supports exactly that with a partial scan: GET /library/sections/{id}/refresh?path=<folder>. plexapi exposes it as section.update(path=folder). A rough shape:

folder = os.path.dirname(mapped_path)
for section in sections:
    if item_type == "episode" and section.type != "show":
        continue
    if item_type == "movie" and section.type != "movie":
        continue
    if any(folder.startswith(loc) for loc in section.locations):
        section.update(path=folder)
        return RefreshResult(success=True, ...)
# only if no section location contains the folder:
return self.refresh_library()

section.locations gives the library root folders, so picking the right section needs no search at all. I think a scan also fits a new sidecar better than item.refresh(), because a new file on disk is a scan job (Plex has to discover the file), not a metadata job.

If you would rather keep the item lookup, I think it has to fetch the section's items and compare part.file client side, which gets slow on big libraries. The folder scan avoids the lookup completely.

Even without the folder scan, the fallback should only refresh sections of the matching type.

Steps to reproduce

  1. Add a Plex server under Settings > Media Servers (empty path mapping, Sublarr and Plex see the same paths).
  2. Let any subtitle download for an episode, or run a wanted search.
  3. The log shows Item not found by path in Plex, falling back to library refresh: <path> and then Triggered Plex full library refresh (N sections).
  4. Confirm directly in the container:
from plexapi.server import PlexServer
s = PlexServer(url, token)
sec = s.library.sections()[0]
sec.search(filters={"Media__Part__file__startswith": "/data/media/tv"})
# plexapi.exceptions.BadRequest: Invalid filter field: Media__Part__file__startswith

Sublarr version

v1.15.0

Deployment

Docker (ghcr.io image)

Database

No response

Logs / Support Export

Sample from 2026-10-01 (paths shortened):


2026-10-01 23:48:29,421 [INFO] [wanted_search:3d4fce6c] mediaserver.plex: Item not found by path in Plex, falling back to library refresh: /data/media/tv/Detective Conan/...
2026-10-01 23:48:29,424 [INFO] [wanted_search:3d4fce6c] mediaserver.plex: Triggered Plex full library refresh (3 sections)
2026-10-01 23:48:45,640 [INFO] [wanted_search:3d4fce6c] mediaserver.plex: Item not found by path in Plex, falling back to library refresh: /data/media/tv/Sayonara Zetsubou Sensei/...
2026-10-01 23:48:45,643 [INFO] [wanted_search:3d4fce6c] mediaserver.plex: Triggered Plex full library refresh (3 sections)


Two full refreshes of all three libraries 16 seconds apart, from one search run.

Counts across all six rotated log files (2026-08-12 to 2026-10-02):


Triggered Plex full library refresh : 491
Triggered Plex item refresh         : 0

Additional context

  • Sublarr 1.15.0 (/app/VERSION), plexapi 4.18.3 (bundled), Plex Media Server 1.43.4.10903, Docker on Linux.
  • Plex libraries: Movies, TV Shows, Bumpers (3 sections). Path mapping empty: Sublarr and Plex both mount the library at /data/media, so mapping is not involved.
  • Plex's own "Scan my library automatically" and partial scan are on, and it does pick up the new sidecars. So for me the cost is the extra full scans of a large HDD library, not missing subtitles. Users who rely on Sublarr's notification instead of Plex's file watcher get the full scan every time.
  • I didn't check the Jellyfin or Emby backends.
  • Searched existing issues for "plex refresh" and "Invalid filter field" first, found nothing.

Activity

  1. Abrechen2 commented on Oct 9, 2026

    @Abrechen2
    Owner

    Thanks for the thorough report — you were right on every point, and the plexapi regex you quoted is exactly why the lookup could never work. The fix follows your suggestion: Sublarr now picks the library whose root folder contains the file and asks Plex for a partial scan of that folder (section.update(path=folder)), no search involved. Only when no library contains the folder is there a full scan, and then only of libraries of the matching type. A failing partial scan is logged as a warning now instead of disappearing at DEBUG. It will be in 1.16.0; I'll update this issue when it ships.

  2. Abrechen2 commented on Oct 10, 2026

    @Abrechen2
    Owner

    Shipped in 1.16.0, now running in production.

  3. albinmedoc commented on Oct 19, 2026

    @albinmedoc

    Should we close this issue?

  4. Svnow132 commented on Oct 20, 2026

    @Svnow132
    Author

    Yes, it's fixed on my end. I've been on 1.16.0 since 2026-10-17 and Sublarr has done 132 partial scans and 0 full library refreshes since then. Thanks for the fix, closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions