Skip to content

fix(availability-sync): prevent false removals for merged-version Plex items#3224

Open
fallenbagel wants to merge 2 commits into
developfrom
fix/availability-sync-merged-plex-versions
Open

fix(availability-sync): prevent false removals for merged-version Plex items#3224
fallenbagel wants to merge 2 commits into
developfrom
fix/availability-sync-merged-plex-versions

Conversation

@fallenbagel

@fallenbagel fallenbagel commented Jul 4, 2026

Copy link
Copy Markdown
Member

Description

The availability sync incorrectly handles merged Plex items where 1080p and 4K versions share a single library item. For movies this can mark 4K copies as deleted immediately after a Plex scan confirms they exist, because both versions receive the same rating key and the sync assumes the shared key means the 4K copy disappeared instead of inspecting the actual Plex versions. It hits movies whose 1080p and 4K files are versions of one Plex item, which is the normal layout for a single movie library with two Radarr instances. The scanner gives both versions the same rating key, and since #2298 the sync treats a shared rating key as proof that the 4K copy is gone, without ever looking at the actual versions. The 4K status then only survives while the Radarr lookup succeeds, so removing the movie from Radarr after import, or running the 4K instance with Enable Scan off, deletes a movie that is sitting in Plex. The removal also wipes the Radarr link on the media row, so a Plex scan restores the status and the next sync run deletes it again, forever.

This PR lets the actual Plex versions decide instead of the rating key comparison for both movies and TV. Availability is now determined from the media versions Plex reports rather than assuming a shared rating key means one copy disappeared. This also fixes several related issues: merged libraries no longer keep stale non-4K statuses after the 1080p version is removed, metadata Plex has not analyzed yet no longer counts as proof that media is missing, TV season availability is resolved from episode versions in merged libraries, and movies now preserve their service metadata while an approved request is still in flight, matching the existing TV behavior.

Existence lookups now also consult every configured Radarr/Sonarr server regardless of Enable Scan. That toggle gates the library import, while these are point lookups by stored id for state Seerr created itself, so a scan-disabled server still counts as evidence that media exists. Without this the sync and the scanners disagree about which servers exist, and the scanners are the ones writing the 4K statuses.

Depends on #3223, the new request test here trips that unhandled rejection without it.

How Has This Been Tested?

Screenshots / Logs (if applicable)

Checklist:

  • I have read and followed the contribution guidelines.
  • Disclosed any use of AI (see our policy)
  • I have updated the documentation accordingly.
  • All new and existing tests passed.
  • Successful build pnpm build
  • Translation keys pnpm i18n:extract
  • Database migration (if required)

Summary by CodeRabbit

  • Bug Fixes
    • Improved 4K movie availability handling so Plex and Radarr data is interpreted more accurately.
    • Prevented non-4K availability from being inferred when only 4K media is present.
    • Kept 4K availability marked correctly for scan-disabled servers.
    • Preserved 4K-related service details when a matching 4K request is still active, and cleared them when no request remains.

@fallenbagel fallenbagel requested a review from Copilot July 4, 2026 19:29
@fallenbagel fallenbagel requested a review from a team as a code owner July 4, 2026 19:29
@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

AvailabilitySync now derives separate 4K enablement flags for movies and shows, preserves identifiers during deletions only when an approved MediaRequest exists for the matching version, and refines Plex existence checks using media widths and mode-aware season caching. Tests add coverage for movie and show 4K detection and deletion handling.

Changes

4K Availability Sync

Layer / File(s) Summary
Server initialization and 4K flags
server/lib/availabilitySync.ts
run() keeps Radarr and Sonarr server lists unfiltered by syncEnabled and computes separate enable4kMovie and enable4kShow flags from configured 4K servers.
Deletion metadata and movie test setup
server/lib/availabilitySync.ts, server/lib/availabilitySync.test.ts
mediaUpdater() checks approved MediaRequest records for both standard and 4K media before clearing identifiers, and the movie deletion tests cover retained versus nulled 4K service fields.
Movie Plex 4K detection
server/lib/availabilitySync.ts, server/lib/availabilitySync.test.ts
mediaExistsInPlex() updates standard and 4K movie existence checks to use Plex media widths and 4K enablement, and the movie tests cover merged versions, ratingKey4k-only items, empty Media arrays, and scan-disabled server evidence.
Show merged-version availability
server/lib/availabilitySync.ts, server/lib/availabilitySync.test.ts
seasonExistsInPlex() uses a mode-aware cache key and width-based episode verification, and the show tests cover merged Plex versions, season rollups, and missing episode metadata cases.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • seerr-team/seerr#2850: Both PRs change seasonExistsInPlex-style episode existence checks, and this PR extends that area with 4K/standard mode-specific Plex verification.
  • seerr-team/seerr#3191: Both PRs depend on MediaRequest state in availability sync, and this PR uses approved requests to decide whether deleted media keeps its identifiers.

Suggested labels: bug

Suggested reviewers: gauthier-th, 0xSysR3ll, M0NsTeRRR

Poem

A rabbit hopped through Plex at night,
Counted widths to sort things right.
4K ears and standard paws,
Kept the rules with careful claws.
Hop, hop—tests now pass in sight. 🐇

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: preventing false removals for merged-version Plex items in availability sync.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adjusts availability sync’s Plex 4K detection logic to rely on actual Plex “versions” (Media width data) instead of ratingKey comparisons, preventing incorrect deletions in merged-version layouts (single Plex item containing both 1080p + 4K versions). Also updates deletion cleanup behavior to preserve external metadata when an approved request is still in flight, and broadens Arr existence lookups to consider configured servers even when scanning is disabled.

Changes:

  • Update Plex movie 4K/non-4K presence checks to evaluate Plex Media version widths (and handle merged rating keys safely).
  • Preserve external service metadata (and Plex rating keys) on deletion when there’s an approved request for the same 4K/non-4K variant.
  • Stop filtering Radarr/Sonarr server lists by syncEnabled so point existence checks consult all configured servers.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
server/lib/availabilitySync.ts Switches Plex merged-version logic to use per-version width checks; preserves metadata when approved requests exist; consults all configured Arr servers for existence checks.
server/lib/availabilitySync.test.ts Adds unit tests covering merged Plex items, analyzed vs. unanalyzed Plex metadata, deletion metadata retention with approved requests, and scan-disabled server existence evidence.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

M0NsTeRRR
M0NsTeRRR previously approved these changes Jul 4, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
server/lib/availabilitySync.ts (1)

920-950: 🚀 Performance & Scalability | 🔵 Trivial

Per-season episode metadata is fetched twice during a 4K show sync.

The 4K show verification loop here calls getChildrenMetadata(season.ratingKey) for each cached season, and seasonExistsInPlex (Line 1038) fetches the same episode children again per season. The early break on the first 4K episode limits this, but for shows being evaluated for removal (the exact path this PR targets) episodes for every season can be fetched twice, doubling Plex API calls per show for large libraries. Consider caching the raw episode results (keyed by season ratingKey) so both checks reuse a single fetch.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/lib/availabilitySync.ts` around lines 920 - 950, The 4K TV
verification path in availabilitySync is fetching season episode metadata twice,
once in the cachedSeasons loop and again in seasonExistsInPlex. Update the 4K
show sync flow so getChildrenMetadata(season.ratingKey) is called once per
season and the raw episode results are reused for both the 4K check and the
season-exists check, ideally by caching them keyed by season ratingKey. Make the
change around the existing plexMedia/cachedSeasons logic and seasonExistsInPlex
so the removal-evaluation path no longer doubles Plex API calls.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@server/lib/availabilitySync.ts`:
- Around line 920-950: The 4K TV verification path in availabilitySync is
fetching season episode metadata twice, once in the cachedSeasons loop and again
in seasonExistsInPlex. Update the 4K show sync flow so
getChildrenMetadata(season.ratingKey) is called once per season and the raw
episode results are reused for both the 4K check and the season-exists check,
ideally by caching them keyed by season ratingKey. Make the change around the
existing plexMedia/cachedSeasons logic and seasonExistsInPlex so the
removal-evaluation path no longer doubles Plex API calls.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: adc276dc-a04b-4dc7-803c-5a8327bcaa34

📥 Commits

Reviewing files that changed from the base of the PR and between 17aff79 and 023a510.

📒 Files selected for processing (2)
  • server/lib/availabilitySync.test.ts
  • server/lib/availabilitySync.ts

@fallenbagel

Copy link
Copy Markdown
Member Author

Don't merge till #3223 is merged

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.

5 participants