github bitr8/agregarr-dev v2.13.0

one hour ago

v2.13.0

A long run of fixes, a new TV placeholder layout, and a big dependency clean-up. The web UI moves to Next.js 15, the Plex client now lives in the repo, and the image drops a lot of dependency baggage.

This release also adds Tracearr as a statistics source, TVDB lists as a collection source, Atmos and HDR10+ badges on shows, quality badges on season posters, Collection Sort Format, rank-based sort titles, a Collection Rank overlay variable, an Edition overlay variable, per-type movie release dates, a Check Layout tool in the overlay editor, and a Resolution preset with an SD icon.

Docker tags

Tag What it tracks
bitr8/agregarr:latest Stable releases. This is what you want.
bitr8/agregarr:2.13.0 Pinned to this exact release.
bitr8/agregarr:develop Bleeding edge. Builds on every push, breaks sometimes.

Upgrading from 2.12.x is a pull. Config volumes are compatible, but the TV placeholder migration below only goes one way, so back up first. Several changes also affect people who never touch the new features. Before you upgrade:

  • TV trailer placeholders migrate to edition folders on the first sync, and the migration only goes one way (fork #139). placeholderEditions is on by default now. Existing TV placeholders move from the Season 00 layout to Show (Year) {edition-Trailer} folders once, on the first sync. An older image won't understand the edition folders afterwards, so back up before upgrading. To skip the migration, stop Agregarr and set "placeholderEditions": false under main in settings.json before updating. There is no UI toggle yet. On Plex below 1.43.3, or while the version can't be read, editions and the migration stay off and placeholders keep the old layout. The migration runs on the first collection sync after the container starts, whether scheduled or started by hand, so the setting has to be in place before then. If the real show arrives and also drops off the Coming Soon source, orphan cleanup removes the trailer up to 7 days later.
  • The first sync after upgrading removes franchise collections that had dropped to one movie, even at the default of 2 (fork #183). Collections that fell below 2 under the old behaviour stayed in Plex until deleted by hand. They now go. Before removing anything, Agregarr reads the library fresh from Plex twice and only removes the collection when both complete reads agree. Removal can lag by a sync, and it never happens in a library that always carries items with no TMDB match. At a minimum of 1, Grab Missing Items can send many more requests, though its year and rating filters still apply. Raising the minimum above every franchise removes the collections but leaves their placeholders until a franchise qualifies again.
  • A one-time overlay re-render if you use a mapped-icon Resolution template (fork #89). The new sd icon is picked up by the default mappings. A custom Resolution element with a mapped icon that falls back to default mappings now shows an SD badge on SD items. Its overlay input hash changes, so resolution-badged items re-render once on the next overlay run. The new Resolution preset also gets an SD badge. If you don't use resolution mapped icons, nothing changes.
  • Promoted collections move from !!!Name to !NNN_Name (PR #114). This is the one intended sort title change on upgrade. Collections on their own sync schedule keep the !!!Name sort title until their own sync runs, or until you run that collection's sync, then move to !NNN_. Untouched installs otherwise keep their existing sort titles.
  • Uploading or importing an SVG icon with scripts is now refused. A template import containing a script, foreignObject, event handler, or javascript: link breaks with an error instead of silently stripping them. Normal icons upload and render as before.
  • Non-owner users can no longer open other users' profile routes. Own-profile requests are unaffected. Anything reading another user through /user/:id as a non-owner account now gets 403.
  • Coming Soon posters for movies in Radarr re-render once to show Radarr's date (fork #157). Collections already set to Random on auto genre, decade, resolution, or content rating collections also get one poster refresh (fork #179).
  • Turning on Skip items with an estimated release date can delete placeholders older than a week on the next sync through normal orphan cleanup (fork #157).
  • Every TMDB Top Rated collection changes on the first sync (fork #190). Top Rated now asks TMDB for at least 300 votes on movies and 200 on TV, matching the floor used by TMDB's own Top Rated list. Previously, titles with one or two votes and a perfect score led the list, so most never matched a real library. Top Rated collections now contain the titles TMDB ranks highest.
  • The first full overlay sync on a TV library refetches stream data for every episode (fork #186). This only happens when a show or season template uses a stream field such as HDR, Dolby Vision, bit depth, Audio Profile, or HDR10+. It costs one batch of Plex requests per 200 episodes, which took about 6 minutes on a 22,000 episode library, then gets cached. Quick sync and single item applies won't fill these fields until that sync has run.
  • Some overlays re-render once on the next overlay run (fork #186). Season posters pick up quality badges and in rules typed in the editor start matching (see Overlays under Fixed). Season templates with a negative rule, such as resolution not 4K, previously matched every season. They now drop off seasons where the rule is false. No template edit is needed.
  • The built-in Audio Codec preset skips shows. Turning on episode scanning won't add audio badges to every show. Use a custom template for show audio badges.
  • Text in the template editor moves to where the poster draws it (fork #189). Posters don't change. A template nudged to look right in the editor now shows where its text actually lands.
  • With Collection Sort Format left off, the first discovery saves each collection's current Plex sort title (PR #156). That means one save for each collection whose value changed. The library list also stops treating a Kometa-style !NNN_ sort title as Agregarr's.
  • When one source of a multi-source collection fails, placeholder cleanup is skipped for that sync. Cleanup previously ran against only the sources that answered, so placeholders from the failed source looked orphaned and were deleted. The placeholders are now kept, and a warning names the failed sources. The collection still updates from the sources that answered, and the run is still reported as failed. Nothing changes when all sources succeed.
  • Plex requests no longer use the plex-api package. An in-repo client replaces it, with keep-alive connections shared across requests. This also removes the deprecated request library and a critical-rated form-data 2.3.3. Headers, JSON/XML handling, error messages, timeouts, retry codes, and GET redirect handling are kept to match, and a contract test passes identically on both. No action needed. Behaviour should be identical, and slow Plex responses aren't cut off by the connection pool. If you see new Plex connection errors, timeouts, or sync failures after upgrading, report them.
  • The runtime image no longer carries node-gyp and its proxy chain. node-gyp, make-fetch-happen, socks-proxy-agent, socks, ip (a high advisory), and @tootallnate/once were compile-time tools never used at runtime. The build stage now deletes them after the production install, and the build breaks if pruning removes a live dependency. Smaller attack surface, no action needed.
  • Dependency refresh. 54 minor and patch updates (38 runtime, 16 dev tooling) plus the Next.js 15 move take the image's OSV findings from 69 to 50 for the refresh, then 50 to 29 for Next 15. Replacing plex-api and stripping node-gyp takes it the rest of the way. An OSV scan of the packages in the current image finds 4 issues, 2 low and 2 moderate, with none high or critical. That is down from 69 at the start of the cycle. Of the four left, cookie, glob, and minimatch only have fixes in new major versions, while deepmerge has no fixed release yet.

Thanks

Cheers too to everyone else who reported the issues below.

What's new

Tracearr as a statistics source

If you moved to Tracearr, you previously had to keep Tautulli running just so Agregarr's Tautulli Statistics collections and the dashboard had something to read. Settings > Sources now has Tracearr Settings (host, port, SSL, URL base, API key, optional server, Test Connection) with a Use Tracearr for statistics toggle.

While it's on, existing Tautulli-type collections (single and multi-source, preview included), the weekly play counts and the collection statistics grid read from Tracearr. Collections keep their type and Plex labels, so nothing needs recreating, and turning the toggle off returns them to Tautulli on the next sync. With it off or Tracearr unset, nothing changes.

Some limits. Tracearr reports at most 365 days, so the dashboard days input is capped there. There is no distinct viewer count per collection. Short windows only reflect history Tracearr itself recorded, and its play counts won't match Tautulli exactly. If Tracearr is unreachable mid-sync, the sync fails and leaves the collection as it was. Needs Tracearr v3.1.4 or later for the top-media endpoint. (fork #65)

TVDB Lists as a collection source

Curated lists (thetvdb.com/lists/matrix) and user lists (thetvdb.com/lists/7149) previously meant rebuilding each list by hand in another source. There is now a TVDB Lists collection type, also available in multi-source, with a Custom List subtype.

Paste the list URL and Validate fetches the list name and whether it contains movies, shows, or both. Items keep the list order. Missing items follow the normal placeholder and request path, filed as TVDBAgregarr. Existing collections are unchanged.

Some limits. A list containing both movies and shows needs one collection per library. A cold cache costs one extra TVDB request per item, and posters fall back to the Agregarr logo. If TVDB can't find an entry and returns 404, it is skipped and logged. Any other lookup failure, or every entry coming back not found, fails the sync and leaves the existing collection alone rather than shrinking it. (fork #87)

Minimum movies for auto franchise collections

A franchise where you owned one film never got a collection, so Grab Missing Items never ran for it. The auto franchise form now has Minimum movies in library, with a default of 2 and a whole-number minimum of 1. Franchises below it are skipped, and an existing collection for them is removed on the next sync. See the upgrade notes above. (fork #183)

The form now has Count only released movies, which is off by default. When enabled, TMDB entries with no release date or a future release date don't count towards the minimum. A film plus an "Untitled Sequel" therefore no longer makes a one-film collection. Films already in your library always count.

With Count only released movies on, collections it no longer keeps are removed on the next sync, but only when Plex confirms they hold fewer than two items. They won't be removed during a sync where a TMDB lookup failed. Once the sequel is released, a removed collection comes back as a new one without carrying over edits made to the old collection in Plex.

Exclude items by Plex label

Placeholders for upcoming titles filled list collections such as IMDb Popular with things you couldn't play yet. The only lever was excluding whole collections. The collection form now has a Label Exclusion tag input beside the collection exclusion.

Items carrying any listed label, for example trailer-placeholder, are dropped before the collection is built. Matching is case-insensitive across every library targeted by the collection. This applies to standard, multi-source, Coming Soon, Letterboxd, TMDB auto franchise, Overseerr, and Tautulli collections, plus quick sync and preview. Leave the list empty and nothing changes.

If the label lookup fails, the items are kept. If labels exclude every item, the existing Plex collection is emptied and kept, and the next sync finds or recreates it. Export/import carries the list. Filtered hubs don't honour it yet, so the section is hidden for them. (fork #149)

TMDB Custom Advanced Filters inside multi-source

The discover-filter builder only existed for single-source TMDB collections, so combining it with other lists meant making separate collections. A TMDB source in a multi-source collection now offers Custom Advanced Filters, using the same builder inside the source card.

Filters are stored per source, used by sync and preview, exported, and kept when converting a single-source advanced collection. Preview now stops paging at the collection's max items instead of paging TMDB until exhausted. There is no per-source sort selector, so advanced sources use the collection's sort, which defaults to TMDB popularity. (fork #141)

Trakt ranking as an Item Order

Trakt Anticipated Coming Soon collections were always re-sorted by release date. That lost Trakt's ranking, and Item Order did nothing for them. Item Order now has a Trakt ranking choice for those collections, covering movies and TV. It keeps Trakt's order through the max items trim and placeholder creation.

Soonest-release-first remains the default. When Trakt Anticipated is a source inside a multi-source collection, the multi-source ordering still applies. (fork #134)

Mid-season episodes for TV Coming Soon (Monitored)

The Monitored subtype only listed shows whose next season premiere fell inside Days Ahead. A show airing weekly in the middle of a season never appeared. A new per-collection checkbox, Include mid-season episodes (TV), now sits under the Coming Soon Monitored server settings.

When enabled, a show appears once if its next monitored, undownloaded episode of any number airs inside the window. These shows get no placeholders, and a mid-season show not in Plex is not listed. It is off by default and carried through preview, export/import, and linked collections. (fork #148)

Skip estimated release dates in Coming Soon

Coming Soon and multi-source collections now have a checkbox under placeholder options: Skip items with an estimated release date. When enabled, movies that only have a cinema date so far, meaning the cinema date plus the 90-day guess, stay out of the collection and get no placeholder until a digital or physical date exists. It is off by default.

One known limit: if every fetched item has an estimated date, the sync sees an empty list and skips cleanup until one real date appears. See the upgrade notes above for what turning it on can delete. (fork #157)

TVDB ID in TV placeholder folder names

TV placeholders for shows not in Sonarr used Title (Year), leaving Plex to match on title and year alone. The new Add TVDB ID to TV placeholder folders setting under Settings > Downloads > Placeholder Root Folders names new folders Title (Year) {tvdb-12345} for shows with a TVDB ID and no Sonarr folder.

It is off by default. Shows in Sonarr keep Sonarr's folder name, and existing placeholders are never renamed or duplicated in either folder form. A legacy folder owned by another show no longer blocks the hinted folder. (fork #153)

TV trailer placeholders get their own Plex edition

TV placeholders lived in a Season 00 special inside the real show. That meant the trailer could appear inside the show and touch its watch state. New TV placeholders now use their own Show (Year) {edition-Trailer} folder, like movie placeholders already do, so the trailer becomes a separate Plex item.

When the real episodes arrive, Agregarr takes the trailer out of Coming Soon collections, puts the real show in, and deletes the trailer files. Collections sharing one trailer are handled together. This needs Plex Media Server 1.43.3 or newer. The migration only goes one way, so read the upgrade notes above first. (fork #139)

Trailer placeholders are unwatched for shared and managed users too

The Plex Webhook reset a played trailer's watched state using only the server owner's token. A shared or managed user who played a trailer still had the movie or show marked watched, and their resume progress was never reset.

On play, stop, or scrobble of a confirmed trailer placeholder, the webhook still unwatches it as the owner. It then does the same as the playing user and resets the resume position. Confirmation happens server-side using a placeholder record or the trailer-placeholder label, and TV episode events are checked against the show. A real special called "Trailer" keeps the owner-only behaviour.

This still needs the Plex Webhook registered in Plex, which requires Plex Pass. Playback history entries are not deleted. A user with no share entry is skipped after the owner pass. (fork #146)

Atmos and HDR10+ badges on shows

A show has no file of its own. That meant a File Path rule such as contains "Atmos" never matched at show level, while Audio Profile only existed for movies.

With Use episode files for quality badges on, episodes now record Audio Profile and HDR10+ from Plex stream data. Shows and seasons then roll those values up in the same way resolution and HDR already work. The most common Audio Profile wins, with ties going to the better format. HDR10+ is on when at least half the episodes have it.

There's also a new HDR10+ condition in the Video group for movies and shows. See the upgrade notes above for the first sync. (fork #186)

Edition variable

There was no way to badge an Extended, Unrated, or IMAX cut. Edition is now available in text elements, conditions, and mapped-icon elements. Matching is case-insensitive, so mappings such as "IMAX" or "Extended Cut" work.

It reads Plex's edition title first, then the {edition-...} tag in the filename. Placeholders never carry an edition, so the Trailer tag doesn't leak into it. Templates that don't use the field don't re-render. (fork #181)

Per-type movie release dates and home-release timing

Rules only had one collapsed release date. A theatrical date, a confirmed home release, and a bare estimate couldn't be told apart. The following movie fields are now available in conditions and text: theatricalReleaseDate, digitalReleaseDate, physicalReleaseDate, daysSinceTheatricalRelease, daysSinceDigitalRelease, daysSincePhysicalRelease, daysSinceHomeRelease (the earliest of digital or physical), and releaseDateSource (digital, physical, estimate, or tmdb).

Day counts are positive once past, negative while still ahead, and 0 on the day. Dates follow the existing TMDB extraction. For placeholders, the digital and physical fields follow Radarr. They are only fetched when a template references them. There is no "still in cinemas" state because there isn't a reliable source. (fork #137)

Collection Rank variable

An overlay couldn't tell where an item sat in a collection, so a numbered "1" to "10" row wasn't possible. The Variable element now has a Collection Rank option under Collection. Pick an Agregarr or Plex collection and the item's 1-based position in that collection's Plex order renders.

Items outside the collection get no number. Only posters whose position changed re-render. Collection Rank never appears on season or episode artwork, and collections spanning several Plex collections, filtered hubs, and Coming Soon configs aren't offered. If a Plex fetch fails, the last known ranks stay. A successful empty fetch clears them.

Known limits: an item that leaves a collection keeps its number until the next full overlay job, there is no rank-only cap condition, and item-level conditions can't test the rank. (fork #49)

Check Layout in the overlay editor

Clipped badge text, colliding text, and elements hanging off the poster previously showed up only after baking a poster. The editor sidebar now has a Check Layout checkbox, off by default. It lists elements beyond the poster edge with rotation taken into account, text that will be clipped, text spilling outside the badge behind it, and text overlapping other text. That includes overlays selected under Preview with Other Overlays.

Clipped text covers a word wider than its box, more lines than allowed, or a font taller than its element. Pairs whose conditions can never both be true are skipped. The check is advisory only. Nothing moves, and rendered output and hashes are untouched. Text width is estimated. (fork #138)

Resolution preset and an SD icon

A lower-resolution badge previously meant building a custom template by hand. There is now an opt-in Resolution preset showing the matching badge for 4K, 1080, 720, 576, and 480. A new sd icon also gives files Plex calls "sd" a badge.

The preset is appended after every existing preset and does nothing until enabled on a library. 4K titles get the icon too, so turn off "4K Resolution" to avoid a double badge. The SD icon isn't opt-in. See the upgrade notes above. (fork #89)

Fix hints on health checks

Most failing checks named the problem and stopped there. Sonarr, Radarr, Cloudflare solver, and Maintainerr checks now lead with a hint for the failure they saw: nothing listening, hostname won't resolve, timeout, rejected API key or proxy, wrong URL base, service error, or SSL. They also note that localhost inside Docker points at the Agregarr container.

The Orphaned Collection Keys, Plex Libraries, and Job Health checks now say what to do next. A refused connection to localhost no longer shows an empty error. The conditions that make each check pass, warn, or fail are unchanged. (fork #78, #94, #61)

Health check for FlixPatrol blocking your solver

When FlixPatrol's Cloudflare refused the solver, Networks Top 10 collections failed in the logs while the health check stayed green. If the solver reaches FlixPatrol but is refused, the Cloudflare Solver check now turns red for 24 hours and walks through routing the solver through a VPN to confirm. Refusal covers HTTP 403/429/503, an unsolved challenge, or a solver challenge failure.

No extra requests are made. The state lives in memory, so restarting clears it until the next sync. (fork #147)

Rank-based promoted sort titles

Promoted collections used a !!!Name prefix whose length depended on the highest rank in the library. Adding or moving one collection rewrote every other sort title. That now works like this:

  • Dragging a collection within the promoted section writes its rank (!007_Recently Added), renumbers the peers it displaced, and marks them to sync. Promote, demote, and delete close the gaps.
  • Ranks use three digits, so Kometa's !010_ style and Agregarr's style interleave in one list. Ranks above 999 are clamped.
  • Typing a rank into the Sort Title field moves the collection the same way. Typing a rank on an A-Z collection asks first, with Keep in A-Z and Keep Promoted buttons. Keep in A-Z discards the typed Sort Title. The same prompt appears when creating a collection.
  • Groups such as Essentials, Directors/Actors, Auto Franchise, genres, and Overseerr user collections sort as a block under one base, with members appending their own name. Separators sort immediately ahead of their group.
  • A Sort Title typed into the field is treated as a full title. Overrides saved before this keep their old meaning, and groups demoted before upgrading aren't re-sorted.

See the upgrade notes above for the one intended change on upgrade. (fork #114)

Collection Sort Format

Collections starting with "The", "A", or "An" all filed under T and A. The only workaround was a hand-typed sort title on each collection.

Settings > Plex now has Collection Sort Format:

  • Off, which is the default
  • Strip, so "The Accountant" sorts as "Accountant"
  • Move to End, so it sorts as "Accountant, The"

This changes only the A to Z sort title, never the collection name. Promoted collections keep their rank.

Agregarr also stops overwriting sort titles it doesn't own. It writes a sort title only when the current value is empty, matches the collection's name, is an article form of the name, or is a rank Agregarr set itself. A sort title entered by hand in Plex is left alone. So is a Kometa !050_Name on a collection Agregarr never promoted.

Clearing the Sort Title field hands it back to the collection name on the next sync. (PR #156)

Exclude lists from Random Lists rotation

Random Lists collections kept landing on the same few lists. With plain HTTP on (the default), Letterboxd discovery reads only the first page of popular lists, about 18, and keeps that pool for 30 days. The only way around it was switching to a hand-picked list.

Add an exclude=URL line for each list to the source file in /config/random-lists/: letterboxd.txt, trakt.txt, imdb.txt, or tmdb.txt.

Excluded lists are left out of your own list, the discovered pool, and the built-in fallbacks. URLs copied from the browser still match discovered URLs because case, www, query strings, trailing slashes, and page or sort suffixes are ignored. If every discovered list is excluded, the built-in lists are used.

Without exclude lines, nothing changes, and existing files aren't rewritten. One catch: a Trakt list copied with its numeric id won't match the slug URL used by discovery. (fork #188)

Fixed

Collections

  • Franchise discovery only saw the first 50 movies when there was no library cache. Libraries larger than 50 movies could get franchise collections built from that slice, leaving most franchises missing or showing fewer owned movies than they had. The fallback now pages through the whole library. Runs with the library cache present are unchanged.
  • "Random" item order was ignored on auto genre collections. Auto genre, decade, resolution, content rating, and actor/director collections are Plex smart collections. Random sent no sort, so Plex fell back to alphabetical. Random now reaches Plex as a random sort, and Plex should reshuffle each time the collection opens. Existing collections pick it up on their next sync, except actor and director collections, which only take a sort when created. That applies to every sort order. Delete and re-sync those. (fork #179)
  • Missing Item Status Sync never moved an auto-requested item to available. It called a Seerr route that doesn't exist for this purpose, got 405, swallowed the error, and left the item at processing or approved even when Seerr showed it Available. It now reads media status from the request objects already fetched by the sync, uses the 4K status for 4K requests, and keeps partially available shows in the re-check set. This also drops one HTTP call per tracked item per run. Items stuck at processing or approved should move on the next sync. (fork #150)
  • Emptying a collection by label exclusion left a dead stored key. Plex removes a regular collection after its last item is taken out, but Agregarr kept the rating key. Every later sync then failed against a collection that no longer existed. The key is now cleared, and the next sync finds or recreates the collection by label.
  • The full sync's last log line always said "completed successfully". It now logs Collections sync completed with N errors as a warning when any collection fails, using the same count as the dashboard's sync card. (fork #129)
  • Several sort title problems came out of the rank-based work. Editing something unrelated no longer turns a stored !010_ into a typed move, and dragging only clears the override for the collection being moved, not its neighbours. Overseerr global and server-owner collections get sort titles again, user collections are no longer rewritten on every sync, and separators no longer get two sort title writes per sync. (fork #114)
  • TMDB collections with Max Items above 1000, or left blank, could fail the whole sync with Failed to fetch discover movies: Request failed with status code 400. TMDB refuses requests beyond page 500, while Trending, Popular, Top Rated, network, keyword, advanced, and Coming Soon kept paging past it. Each TMDB loop now stops at page 500 and keeps the items collected so far. Advanced filters already stopped there but logged a warning. A very large Max Items can still make the sync slow, mostly because Plex has to put thousands of items in order. (fork #190)
  • Use TMDB Franchise Poster could pick a poster in another language when TMDB had none in your language. It now tries your language first, then English, then posters without text, taking the best rated poster from each group. This costs one extra cached TMDB request per franchise per sync, and only when the option is on. (fork #183)

Placeholders

  • Multi-source cleanup could delete placeholders belonging to a failed source. See the upgrade notes above.
  • Trailer search error logging used the wrong level. A trailer rejected by the duration filter was logged as an error, "Failed to download YouTube trailer", instead of the intended info line. The rejection message now carries yt-dlp's stdout.
  • Trailer search and download inputs are now bounded. yt-dlp search runs from a fixed path with a 256 KiB output cap and a 30-second timeout. The result count is clamped from 1 to 50, the query is capped at 200 characters, and a % in a title no longer reaches the output template and renames the file. Trailer behaviour is otherwise unchanged.

Overlays

  • Coming Soon posters now agree with the placeholder date. A placeholder is created from Radarr's digital or physical date, but the poster re-resolved the date from TMDB for your region. That could produce Radarr 11 Nov against poster 01 Dec. Placeholder movies in Radarr now show Radarr's earliest digital or physical date, and the estimated flag clears when Radarr has a real date. TMDB still fills the gap when Radarr has no date. Items already in Plex are unchanged because Radarr's digital date on catalogue films is often a streaming re-add. (fork #157)
  • "Item has no poster in Plex" now says what was tried. The overlay log gave no clue which sources had been checked. It now reads like No base poster available. Tried: TMDB (item has no TMDB id), Plex (item has no poster in Plex). A local file rejected by validation is reported as invalid or unreadable instead of not found. This only changes the error text, not poster output. Lookup errors such as timeouts still surface as their own error. (fork #110)
  • Maintainerr season IMDb ratings dropped when Posterizarr was off. The Maintainerr season subpass threw away ratings drawn by the full sync, so flagged seasons were redrawn without the IMDb rating and hashed a different context on every full sync. The subpass now reuses those ratings. (fork #120)
  • Reset Posters and the overlay test had two separate problems. Cancelling Reset Posters while it looked up season and episode rows now logs the cancellation like the other exits (fork #120). The overlay test also no longer labels WebP bytes as JPEG when the Posterizarr toggle changes mid-request.
  • Season posters didn't get resolution, HDR, or audio badges. Plex doesn't keep file information on a season, and seasons weren't rolling it up from their episodes as shows did. Each season now rolls up its own episodes, so a 1080p first season of a mostly 4K show stays 1080p. (fork #186)
  • in conditions written in the template editor didn't match. The editor saves the value as text (4k,2160), but in only matched a list, which is how the presets store it. Comma-separated text now matches after trimming and without case sensitivity. The editor preview and layout warnings read it the same way. A value containing a comma still can't be matched with in from the editor. (fork #186)
  • The template editor drew text higher than the poster, by about a sixth of the font size with Inter and by different amounts with other fonts. It also shrank text to fit short boxes and wrapped long text. The editor now draws one line at full size on the same middle line used by the poster, cuts it off at the box edge, and drops typed line breaks as the poster does. Fonts shipped as separate regular and bold files can still sit about 1% of the font size off in bold. (fork #189)
  • A Mapped element showed an empty box in the editor when the preview's sample value had no mapping. That meant an Edition mapping for IMAX or Unrated couldn't be placed. The editor now shows the first mapping dimmed, with a tooltip. Posters are unchanged. (fork #181)

Dashboard

  • The Collection Statistics card showed "Request failed with status code 400" when Tautulli wasn't configured. It looked for the server's "Tautulli not configured" text in the wrong place. It now shows the setup panel explaining that Tautulli is needed, with a link to its settings. Nothing changes when Tautulli is configured.
  • Dashboard and missing-items cards now show the server's error text instead of "Request failed with status code 500". Responses without a readable message, such as a proxy's HTML error page, keep the old text. Settings forms are untouched.

Security

  • Signed-in users could read and edit other users' profiles. Any signed-in user could read another user's settings, including email, and change the username, display name, or email for any user id, including the owner's. That matters because sign-in matches Plex accounts by email. Routes containing an :id under /user now return 403 unless the caller is the owner or that same user. Own-profile requests, owner requests, and the user list are unchanged.
  • Uploaded SVG icons are checked and served sandboxed. Icon uploads and template imports containing scripts, foreignObject, event handlers, or javascript: links are refused with an error instead of being regex-stripped. Anything that isn't a parseable SVG is also refused. The icon route sends a sandboxing Content-Security-Policy and nosniff. See the upgrade notes above.
  • File-serving routes are rate limited, and the browse endpoint checks real paths. Nine file-serving routes flagged by CodeQL now have rate limits. The unauthenticated collection poster route has its own bucket, so a flood of 404s from one address can't lock an admin out of the other file routes. The filesystem browse deny-list checks the resolved real path, which means a symlink into /proc is refused. The unused POST /collections/poster upload route is gone.

Other

  • The Posterizarr integration checkbox and eight other text-less checkboxes now have an accessible label. No visible change.
  • The Watch Provider Region tooltip said the setting only affected the Streaming Provider overlay. It also selects which country's release dates are used by overlays and Coming Soon placeholders, and now says so.
  • The Coming Soon Monitored description now reads "Unreleased monitored movies, and shows with an upcoming season premiere", since TV only looks at season premieres. (fork #148)
  • Season premiere selection is now order-independent. Premieres are sorted by air date before choosing the next one, so the earliest wins when Sonarr returns seasons out of order.
  • Seven sort title prompts were registered under the wrong message ids, so translations never reached them. The English text is unchanged.

Changed

  • Web UI moves from Next.js 12 to 15.5.28. Next 12 was out of support and carried 16 advisories, plus 5 in its bundled postcss. Pages should look and behave the same, and now hydrate without the silent full re-render in the browser. React stays on 18. No settings or data change. /_next/image still returns 404.
  • Plex requests go through an in-repo client. See the upgrade notes above.
  • Trailer downloads use yt-dlp 2026.10.26, checksum-verified during the image build. The previous pin would have passed 90 days old on 17/11, after which YouTube downloads fail and the static placeholder video is used.
  • Seven unused packages are gone from the image: email-templates, nodemailer, pug, zod, semver, web-push, and play-dl. multer is now a declared direct dependency on 2.x. express-openapi-validator moves to 5.6.2, which drops the nested multer 1.x. tar is pinned to 7.5.22, covering 12 advisories that only apply at install time.
  • react-select 5.10.2 and swr 2.5.1. Both were held back by typing problems rather than runtime ones. react-select adds listbox and option roles plus revised aria-live announcements. swr clears a hook's error once new data arrives. No setting, route, or stored data changes.
  • Image build. Fonts come from a pinned google/fonts commit. The Fira Code zip and yt-dlp are checksummed, and the develop build runs a smoke test against the freshly built image before the tag moves. The image optimiser must not answer, while /setup must.

Don't miss a new agregarr-dev release

NewReleases is sending notifications on new releases.