Skip to content

fix(discover): fix tv title sorting and validate sortBy per media type - #3305

Open
fallenbagel wants to merge 1 commit into
developfrom
fix/discover-sorting-title
Open

fix(discover): fix tv title sorting and validate sortBy per media type#3305
fallenbagel wants to merge 1 commit into
developfrom
fix/discover-sorting-title

Conversation

@fallenbagel

@fallenbagel fallenbagel commented Jul 29, 2026

Copy link
Copy Markdown
Member

Description

The TV discover page's title sort sent sort_by=original_title.* to /discover/tv, which is a movie-only value. TMDB silently ignores invalid sort_by parameters and returns its default popularity order, so sorting series by title did nothing. Sort options are now split per media type and validated at the route (previously any string was cast and forwarded unchecked), and TV title sorting uses original_name.*.

Note

Known limitation (upstream)

  • The title/name were deliberately not adopted as when I verified against the live TMDB API, their sort orderings are identical to the original_* variants, as in sort_by=name.desc and sort_by=original_name.desc return matching ID sequences on /discover/tv, as do title.desc and original_title.desc on /discover/movie. Therefore, switching movies to title would change nothing while widening the scope. Thus, this PR keeps Movie's original_title.*, and similarly adopts original_name.* for TV as the value for sorting.
  • TMDB orders title sorts by the original-language title in code-point order. The language parameter affects display strings only. Non-Latin-script titles therefore cluster together in title sorts regardless of their displayed names, no TMDB sort option orders by the localized title, and this cannot be corrected client-side because pagination is server-side. Consistent with earlier reports: title vs original_title exact match, staff confirmation that results are not sorted by translated titles.

Invalid sortBy values, including the original_title.* the UI previously emitted for TV are now ignored and fall back to TMDB's default order rather than erroring.

Lastly, the blocklisted tags job now iterates only valid, distinct sort values per media type (previously TV queries and movie queries per tag used cross-type values that silently degraded into duplicate popularity-ordered pages so now this should make fewer requests per tag with strictly better coverage, and keyword details are fetched once per tag instead of once per media type).

How Has This Been Tested?

  • Tested against the live TMDB API: sort-order equivalence of the localized and original title fields on both discover endpoints, and that the language parameter affects ordering.
curl -s 'curl -s 'https://api.themoviedb.org/3/discover/tv?api_key=KEY&language=en-US&sort_by=name.desc&page=5' | jq -c '[.results[].id]'
curl -s 'https://api.themoviedb.org/3/discover/tv?api_key=KEY&language=en-US&sort_by=original_name.desc&page=5' | jq -c '[.results[].id]'
# both: [197074,65237,251479,288693,297953,126991,320346,291393,94222,89150,102899,92061,154589,92114,313440,210107,321696,68814,203164,57433]
# movie pair (title.desc vs original_title.desc) likewise identical
  • Tested title asc/desc on Discover Movies and Discover Series in a dev instance, confirmed sorting now works for /tv.

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

  • New Features
    • Movie and TV discovery now offer media-specific sorting options.
    • TV title sorting now uses the correct original-name ordering.
  • Bug Fixes
    • Improved discovery query validation ensures only supported sort options are accepted for movies vs TV.
    • Blocklisted-tag processing now unifies paging for movies and TV, with more accurate totals, consistent progress updates, and improved cancellation behavior.

@fallenbagel
fallenbagel requested a review from a team as a code owner July 29, 2026 07:41
Copilot AI review requested due to automatic review settings July 29, 2026 07:41
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d9b7bca7-1731-4bfc-ae66-eab81bb0b774

📥 Commits

Reviewing files that changed from the base of the PR and between b8418b0 and 1e95c2e.

📒 Files selected for processing (5)
  • server/api/themoviedb/index.ts
  • server/job/blocklistedTagsProcessor.ts
  • server/routes/discover.ts
  • src/components/Discover/DiscoverMovies/index.tsx
  • src/components/Discover/DiscoverTv/index.tsx
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/components/Discover/DiscoverTv/index.tsx
  • src/components/Discover/DiscoverMovies/index.tsx
  • server/api/themoviedb/index.ts
  • server/job/blocklistedTagsProcessor.ts
  • server/routes/discover.ts

📝 Walkthrough

Walkthrough

TMDB sorting is represented separately for movies and TV, with media-specific API validation and discovery types. TV title sorting uses original_name, and blocklist processing shares paging logic across movie and TV tags.

Changes

TMDB sorting and discovery

Layer / File(s) Summary
Media-specific sort contracts
server/api/themoviedb/index.ts
Movie and TV sort iterables and union types are exported, and discovery options now accept the matching media-specific sort type.
Typed discovery consumers
server/routes/discover.ts, src/components/Discover/DiscoverMovies/index.tsx, src/components/Discover/DiscoverTv/index.tsx
Movie and TV routes validate separate sort enums, UI components use matching types, and TV title sorting maps to original_name.asc and original_name.desc.
Per-tag media processing
server/job/blocklistedTagsProcessor.ts
Blocklist generation processes each tag across movie and TV discovery through shared paging, throttling, progress, cancellation, and error handling logic.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: copilot

Poem

A bunny sorts the films with care,
Then hops through shows with names to spare.
Tags march on through pages bright,
TV titles now sort right.
“Thump thump!” says Bun—what a delightful fix!

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately reflects the main discover sorting and sortBy validation changes.
Linked Issues check ✅ Passed The TV discover sort fix addresses the linked issue by using TV-specific sort values instead of movie-only ones.
Out of Scope Changes check ✅ Passed The route validation, sort-option split, and blocklisted tag job updates align with the stated discover sorting objectives.

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

This PR fixes TV Discover title sorting by switching TMDB TV sort values from the movie-only original_title.* to original_name.*, and tightens server-side validation so only media-type-appropriate sortBy values are forwarded to TMDB. It also refactors the blocklisted tags processor to iterate only valid sort modes per media type and reduce redundant TMDB calls.

Changes:

  • Update TV Discover “Title” sorting to use original_name.asc|desc (and split sort option typing between Movies and TV in the UI).
  • Validate sortBy per discover route using Zod enums backed by media-type-specific sort option iterables.
  • Refactor the blocklisted tags job to iterate valid sort values per media type and fetch keyword details once per tag.

Reviewed changes

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

Show a summary per file
File Description
src/components/Discover/DiscoverTv/index.tsx Switch TV title sort to original_name.* and use TV-specific sort option typing.
src/components/Discover/DiscoverMovies/index.tsx Use movie-specific sort option typing (no behavior change).
server/routes/discover.ts Split and validate sortBy per media type; stop forwarding arbitrary strings to TMDB.
server/job/blocklistedTagsProcessor.ts Iterate distinct valid sort values per media type; reduce redundant keyword-detail fetches.
server/api/themoviedb/index.ts Split sort option lists/types into movie vs TV, with shared common options.
Comments suppressed due to low confidence (1)

server/api/themoviedb/index.ts:69

  • The server-side sortBy validation for TV now only allows values in TvSortOptionsIterable. Previously the API forwarded any string to TMDB, so callers/bookmarks using TMDB's name.asc|desc aliases would now silently fall back to default popularity ordering. If you want to keep compatibility while still validating by media type, consider allowing name.* alongside original_name.*.
export const TvSortOptionsIterable = [
  ...CommonSortOptionsIterable,
  'first_air_date.desc',
  'first_air_date.asc',
  'original_name.desc',
  'original_name.asc',
] as const;

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

Comment thread src/components/Discover/DiscoverTv/index.tsx
Comment thread server/api/themoviedb/index.ts

@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.

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@server/job/blocklistedTagsProcessor.ts`:
- Around line 155-159: Update the loop using query, page, and sortBy so it
enumerates every sort/page combination exactly once rather than applying
independent modulo cycles. Derive each value from the same linear query index
and preserve fixedSortMode behavior, ensuring all pageLimit pages are paired
with all available sortOptions without omissions or duplicates.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 42d55785-2a22-40f1-a21f-de6f24c672ec

📥 Commits

Reviewing files that changed from the base of the PR and between 95e18de and b8418b0.

📒 Files selected for processing (5)
  • server/api/themoviedb/index.ts
  • server/job/blocklistedTagsProcessor.ts
  • server/routes/discover.ts
  • src/components/Discover/DiscoverMovies/index.tsx
  • src/components/Discover/DiscoverTv/index.tsx

Comment thread server/job/blocklistedTagsProcessor.ts
The TV discover page's title sort sent `sort_by=original_title.*` to `/discover/tv`, which is a
movie-only value. TMDB silently ignores invalid `sort_by` parameters and returns its default
popularity order, so sorting series by title did nothing. Sort options are now split per media type
and validated at the route (previously any string was cast and forwarded unchecked), and TV title
sorting uses `original_name.*`.

fix #3304
Copilot AI review requested due to automatic review settings July 29, 2026 08:03
@fallenbagel
fallenbagel force-pushed the fix/discover-sorting-title branch from b8418b0 to 1e95c2e Compare July 29, 2026 08:03

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

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

Comments suppressed due to low confidence (1)

src/components/Discover/DiscoverTv/index.tsx:45

  • TV sort option values were changed from original_title.* to original_name.*, but prepareFilterValues(router.query) still accepts any sortBy string. If a user opens an older bookmarked URL like ?sortBy=original_title.asc, preparedFilters.sortBy becomes a controlled <select> value that doesn’t match any <option>, which can render a blank selection / cause React controlled-value warnings. Consider normalizing/clearing unknown sortBy values against the local SortOptions list before the component uses preparedFilters.
  TmdbRatingAsc: 'vote_average.asc',
  TmdbRatingDesc: 'vote_average.desc',
  TitleAsc: 'original_name.asc',
  TitleDesc: 'original_name.desc',
} as const;

@seerr-automation-bot seerr-automation-bot added this to the v3.5.0 milestone Jul 30, 2026
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.

sorting by title for tv series is defaulting to popularity

4 participants