Fix for movies and tv shows stuck at the front of recently added

Server Version#: Current Plex Server for Windows Version as of 2025-01-13 22:27:00

I hope this guide helps someone. Took me a bit to figure out the query for fixing tv shows mess. To be clear, I used ChatGPT to help with writing this quide, but the way I approached fixing stuck tv shows was my idea. I just used ChatGPT as a sounding board while troubleshooting. Also, between movies and TV shows, you need to keep track of the metadata_type and library_section_id values. They may be different from the values I have in this guide. If you want to use the same values you would have had to have created at least two other plex libraries before adding your tv-show library I first created a movies (ultra HD) library, followed by a movies (HD) library, followed by my TV show library

Guide: Fixing Stuck Movies and TV Shows in Plex’s Recently Added

If you’re dealing with movies or TV show episodes that are perpetually stuck at the front of the “Recently Added” section in Plex, this guide is for you. By directly addressing the underlying database timestamps, we can correct this issue once and for all.


Important Notes

  1. Back Up Your Plex Database:
    Before proceeding, make a backup of your Plex database file (com.plexapp.plugins.library.db). This ensures you can restore it in case anything goes wrong.

  2. Prerequisite Knowledge:
    This guide assumes you’re comfortable working with SQLite and understand how to manipulate the Plex database. If you’re new to this, take some time to familiarize yourself with SQLite tools like DB Browser for SQLite.

  3. Choose Your SQLite Client:
    For this guide, we use DB Browser for SQLite, but any SQLite client should work.


Step 1: Disable Plex Database Triggers

To safely update the database, you need to temporarily disable two triggers that affect the metadata_items table:

  • fts4_metadata_titles_before_update_icu
  • fts4_metadata_titles_after_update_icu

How to Disable the Triggers:

  1. Locate the triggers under the “Triggers” node in your SQLite client.
  2. Right-click each trigger and delete them (don’t worry, we’ll recreate them later).
    • Optionally, note down the SQL statements for the triggers before deleting them:
      -- Trigger: fts4_metadata_titles_before_update_icu
      CREATE TRIGGER fts4_metadata_titles_before_update_icu
      BEFORE UPDATE ON metadata_items
      BEGIN 
          DELETE FROM fts4_metadata_titles_icu WHERE docid=old.rowid;
      END;
      
      -- Trigger: fts4_metadata_titles_after_update_icu
      CREATE TRIGGER fts4_metadata_titles_after_update_icu
      AFTER UPDATE ON metadata_items
      BEGIN 
          INSERT INTO fts4_metadata_titles_icu(docid, title, title_sort, original_title)
          VALUES(new.rowid, new.title, new.title_sort, new.original_title);
      END;
      

Step 2: Fix Movies

Bulk Update All Movies:

If you want all movies to have their added_at timestamp match their original release date (originally_available_at), use this query:

UPDATE metadata_items
SET added_at = originally_available_at
WHERE library_section_id = 1 AND metadata_type = 1;

Update Specific Stuck Movies:

If only a few movies are stuck at the front, identify the last correct added_at timestamp and update the problematic entries:

UPDATE metadata_items
SET added_at = originally_available_at
WHERE library_section_id = 1 AND metadata_type = 1 AND added_at > LAST_VALID_TIMESTAMP;

Step 3: Fix TV Shows

Create a Sorted Temporary Table:

Run this query to sort TV show episodes by their air date (originally_available_at) and store the results in a temporary table:

CREATE TEMP TABLE sorted_items AS
SELECT 
    M.id,
    M.library_section_id,
    M.metadata_type,
    M.parent_id,
    M.title,
    -- TV Show Title
    CASE 
        WHEN M.metadata_type IN (3, 4) THEN 
            (SELECT M1.title FROM metadata_items AS M1 WHERE M1.id = 
                (SELECT M2.parent_id FROM metadata_items AS M2 WHERE M2.id = M.parent_id LIMIT 1))
        ELSE NULL
    END AS tv_show_title,
    -- Season Title
    CASE 
        WHEN M.metadata_type = 4 THEN 
            (SELECT M1.title FROM metadata_items AS M1 WHERE M1.id = M.parent_id)
        ELSE NULL
    END AS episode_season,
    -- Episode Number
    CASE 
        WHEN M.metadata_type = 4 THEN M."index"
        ELSE NULL
    END AS episode_number,
    M.year,
    DATETIME(M.originally_available_at, 'unixepoch') AS originally_available_at_dt,
    M.originally_available_at
FROM metadata_items AS M
WHERE library_section_id = 3 AND metadata_type IN (2, 3, 4)
ORDER BY originally_available_at_dt DESC;

Update added_at for TV Show Episodes:

After creating the temporary table, update the added_at column in the main table:

UPDATE metadata_items
SET added_at = (
    SELECT originally_available_at
    FROM sorted_items
    WHERE sorted_items.id = metadata_items.id
)
WHERE id IN (SELECT id FROM sorted_items);

Step 4: Verify the Changes

Run the following query to ensure that added_at matches originally_available_at:

SELECT id, title, DATETIME(added_at, 'unixepoch') AS added_at_dt, DATETIME(originally_available_at, 'unixepoch') AS originally_available_at_dt
FROM metadata_items
WHERE id IN (SELECT id FROM sorted_items)
ORDER BY originally_available_at_dt ASC;

Step 5: Recreate the Triggers

Finally, recreate the deleted triggers:

CREATE TRIGGER fts4_metadata_titles_before_update_icu
BEFORE UPDATE ON metadata_items
BEGIN 
    DELETE FROM fts4_metadata_titles_icu WHERE docid=old.rowid;
END;

CREATE TRIGGER fts4_metadata_titles_after_update_icu
AFTER UPDATE ON metadata_items
BEGIN 
    INSERT INTO fts4_metadata_titles_icu(docid, title, title_sort, original_title)
    VALUES(new.rowid, new.title, new.title_sort, new.original_title);
END;

Step 6: Cleanup

  • The temporary table (sorted_items) will automatically be dropped when you close the SQLite session.
  • Write your changes to the database file.

Conclusion

This method ensures your Plex library’s “Recently Added” section reflects accurate dates, both for movies and TV shows. By leveraging the originally_available_at field, you create a consistent and logical order that aligns with media release dates.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.