fix: add TheMovieDb provider fallback for Jellyfin scanner#2605
fix: add TheMovieDb provider fallback for Jellyfin scanner#2605YakGravity wants to merge 8 commits intoseerr-team:developfrom
Conversation
Shokofin writes TMDB IDs using the legacy Jellyfin provider key "TheMovieDb" instead of "Tmdb". This causes Seerr to miss all anime managed by Shokofin during library sync, showing them as unavailable despite being present in Jellyfin. Adds nullish coalescing fallback (Tmdb ?? TheMovieDb) in three places in the Jellyfin scanner for both movie and TV show processing.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughUpdate in the Jellyfin scanner to derive Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). 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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
server/lib/scanners/jellyfin/index.ts (1)
230-233: Consider using||instead of??for consistency with the condition.Line 230 uses
||(falsy check), while line 233 uses??(nullish check). IfTmdbwere an empty string andTheMovieDbhad a valid ID, the condition would pass butNumber("")would yield 0.This is likely an edge case since Jellyfin provider IDs are typically either present with values or absent, but using
||on line 233 would match the condition's semantics.Suggested change for consistency
if (metadata.ProviderIds.Tmdb || metadata.ProviderIds.TheMovieDb) { try { tvShow = await this.getTvShow({ - tmdbId: Number(metadata.ProviderIds.Tmdb ?? metadata.ProviderIds.TheMovieDb), + tmdbId: Number(metadata.ProviderIds.Tmdb || metadata.ProviderIds.TheMovieDb), });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@server/lib/scanners/jellyfin/index.ts` around lines 230 - 233, The condition checks metadata.ProviderIds.Tmdb || metadata.ProviderIds.TheMovieDb but the call to this.getTvShow uses the nullish coalescing operator (metadata.ProviderIds.Tmdb ?? metadata.ProviderIds.TheMovieDb); change that to use the logical OR (metadata.ProviderIds.Tmdb || metadata.ProviderIds.TheMovieDb) so the chosen value matches the condition semantics before calling Number(...) in the getTvShow invocation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@server/lib/scanners/jellyfin/index.ts`:
- Around line 230-233: The condition checks metadata.ProviderIds.Tmdb ||
metadata.ProviderIds.TheMovieDb but the call to this.getTvShow uses the nullish
coalescing operator (metadata.ProviderIds.Tmdb ??
metadata.ProviderIds.TheMovieDb); change that to use the logical OR
(metadata.ProviderIds.Tmdb || metadata.ProviderIds.TheMovieDb) so the chosen
value matches the condition semantics before calling Number(...) in the
getTvShow invocation.
|
Please update your pr description with the proper pr template. You're missing several things from the checklist. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@server/lib/scanners/jellyfin/index.ts`:
- Line 63: The tmdbId assignment uses the nullish coalescing operator (??) which
differs from other checks (lines using ||) and will not fallback when
ProviderIds.Tmdb is an empty string; update the assignment for tmdbId to use the
logical OR operator so it falls back to metadata.ProviderIds.TheMovieDb for
falsy values (empty string, 0, undefined, null) before calling Number, i.e.,
replace the ?? between metadata.ProviderIds.Tmdb and
metadata.ProviderIds.TheMovieDb with || so the behavior is consistent with the
other checks.
|
You forgot to run |
There was a problem hiding this comment.
Pull request overview
Adds a Jellyfin scanner fallback so items that store TMDB IDs under the legacy TheMovieDb provider key (e.g., written by Shokofin) can still be matched during Seerr library sync.
Changes:
- Movie scanning: derive
tmdbIdfromProviderIds.Tmdbwith fallback toProviderIds.TheMovieDb - TV scanning: treat
ProviderIds.TheMovieDbas a valid TMDB identifier source when loading show metadata
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let tmdbId = Number( | ||
| metadata.ProviderIds.Tmdb || | ||
| metadata.ProviderIds.TheMovieDb || | ||
| null | ||
| ); |
There was a problem hiding this comment.
metadata.ProviderIds is typed as { Tmdb?: string; Imdb?: string; Tvdb?: string; AniDB?: string; } (see @server/api/jellyfin), so accessing metadata.ProviderIds.TheMovieDb will fail TypeScript compilation. Add TheMovieDb?: string to the ProviderIds type (or use an index signature / safe accessor) so this fallback is type-safe.
| if (metadata.ProviderIds.Tmdb || metadata.ProviderIds.TheMovieDb) { | ||
| try { | ||
| tvShow = await this.getTvShow({ | ||
| tmdbId: Number(metadata.ProviderIds.Tmdb), | ||
| tmdbId: Number( | ||
| metadata.ProviderIds.Tmdb || | ||
| metadata.ProviderIds.TheMovieDb | ||
| ), |
There was a problem hiding this comment.
Same typing issue here: metadata.ProviderIds.TheMovieDb is not part of the JellyfinLibraryItemExtended.ProviderIds interface, so this will not type-check. Update the Jellyfin ProviderIds type to include TheMovieDb?: string (or otherwise access it safely) to keep the scanner compiling.
Description
Shokofin (a Jellyfin plugin for anime managed by Shoko Server) writes TMDB IDs using the legacy Jellyfin provider key
TheMovieDbinstead ofTmdb. This causes Seerr to miss all anime managed by Shokofin during library sync, showing them as unavailable despite being present in Jellyfin.This PR adds a fallback in three places in the Jellyfin scanner:
extractMovieIds):metadata.ProviderIds.Tmdb || metadata.ProviderIds.TheMovieDb || nullprocessJellyfinShow): Added|| metadata.ProviderIds.TheMovieDbto the if-conditionprocessJellyfinShow):Number(metadata.ProviderIds.Tmdb || metadata.ProviderIds.TheMovieDb)for the tmdbId lookupNo breaking changes: When
Tmdbexists (standard Sonarr/Radarr),||short-circuits and behavior is unchanged. The fallback only activates for items using the legacyTheMovieDbkey.How Has This Been Tested?
Tested on a live Jellyfin + Shokofin setup with multiple anime titles. Before the fix, all Shokofin-managed anime showed as unavailable in Seerr. After the fix, library sync correctly identifies them (e.g. "Frieren: Beyond Journey's End" returns
mediaInfo.status: 4PARTIALLY_AVAILABLE). Non-anime content (Sonarr/Radarr managed) continues to work without regression.Screenshots / Logs (if applicable)
N/A
Checklist:
pnpm buildpnpm i18n:extractAI Disclosure
The root cause analysis (Shokofin using
TheMovieDbvsTmdbprovider key) was identified through manual debugging with log analysis. Claude was consulted for reviewing the fix approach and drafting the PR description. The code changes were authored and tested manually.Summary by CodeRabbit