v2.9.0
FlixPatrol collections are broken on upstream and have been since March. Cloudflare fingerprints the TLS layer now, so no amount of header spoofing fixes it. This release adds FlareSolverr support, built-in headless Chromium, and per-platform fallback pages so streaming top 10 collections actually work again. Behind that: health checks, library essentials, collection export/import, a security pass across every route, and eighteen fixes from the fork tracker. Everything here has been running live on a production server.
Docker tags
| Tag | What it tracks |
|---|---|
bitr8/agregarr:latest |
Stable releases. This is what you want. |
bitr8/agregarr:2.9.0 |
Pinned to this exact release. |
bitr8/agregarr:develop |
Bleeding edge. Builds on every push, breaks sometimes. |
Upgrading from 2.8.x is a pull; config volumes are compatible. Release tags ship amd64 and arm64 (Apple Silicon, RPi 4+).
What's new
FlixPatrol and Cloudflare: FlareSolverr support
Cloudflare now fingerprints the TLS layer on FlixPatrol requests. Node's HTTP client gets challenged regardless of headers, so every FlixPatrol collection (Networks Top 10, streaming charts) has been broken on upstream since around March. curl gets blocked too as of August. The country dropdown collapses to "Global" only and previews return nothing.
This release adds fetch paths for scraped sources, in order of reliability:
- FlareSolverr (recommended). If you run a FlareSolverr instance (many people already do for Prowlarr/Jackett), point Agregarr at it under Settings > Sources > FlareSolverr URL. Requests route through a real browser session that passes the challenge. This is the path that works reliably.
- Built-in headless Chromium. The Docker image bundles Chromium and uses it by default when no FlareSolverr URL is set. Works in most environments but can fail on resource-constrained hosts or certain VPS setups.
- Plain HTTP. A toggle under Settings for environments where Cloudflare isn't an issue. Off by default.
FlixPatrol also dropped four platforms (Crunchyroll, Discovery+, Peacock, Hulu) from their global overview page. The scraper now falls back to each platform's own Top 10 page when the overview has no section for it. Peacock and Hulu only publish US charts, so those use the US page. (upstream #609, #610)
Health checks
Agregarr now runs thirteen diagnostic checks on a schedule and surfaces the results in a Health panel under Settings. Plex connectivity, Sonarr/Radarr reachability, TMDB, Maintainerr, overlay config validity, job freshness, database integrity, disk space, and more.
Checks that fail once aren't flagged immediately. Transient failures (a Plex restart, a network hiccup) get a grace window before the check turns red. Each check can be muted individually if you know about it and don't want to see it.
Job runs are persisted now too, with per-job detail, so you can see what the last sync or overlay run actually did rather than just whether it finished. A per-job watchdog caps quick syncs at 5 minutes and full syncs at 2 hours, so a stuck job doesn't hold the queue indefinitely.
Library essentials
A new collection type that generates smart collections from your library's own attributes: genre, decade, resolution, or content rating. Pick a library, pick a subtype, and Agregarr builds a collection for each value it finds (Action, Comedy, Drama, 2020s, 4K, and so on).
Each subtype supports include and exclude mode. Include mode creates collections only for the values you name. Exclude mode creates collections for everything except the values you name. Both generate Plex smart collections with the correct filters, so the membership stays current without Agregarr doing anything after creation.
Auto-poster generation works on essentials too: a grid of the collection's artwork, same as any other collection. (fork #31, #34)
Collection config export and import
Export your collection configs as a JSON file and import them back, on the same instance or a different one. Useful for backups, migration, or sharing a setup with someone.
Exports carry resolved source titles so the import preview is readable, and multi-source collections let you pick which sources to bring across. Batch IDs track which import a config came from. Deprecated fields are migrated on import so an export from an older version still works.
Label collections
Collections can target items by their Plex labels now. If you label films or shows in Plex (manually or through another tool), you can build a collection from those labels without maintaining a list. Community contribution from Damienlee69. (fork #48)
Estimated release date flag
Overlay templates now get isEstimatedReleaseDate, a boolean that's true when the rendered date is a fabrication (typically theatrical date + 90 days as a guess at the digital release). Templates can use it to mark estimated dates differently, so a viewer knows the date might shift.
The theatrical+90 estimate also no longer loses a day when it crosses a DST boundary.
Overlay template editor: canvas size
Canvas was locked to 1000x1500. Width and height are now configurable in the sidebar, so landscape and non-standard templates render at the right aspect ratio in the editor instead of clipping. (fork #52)
Smaller additions
- Trailer ribbon presets. Two overlay presets that badge placeholder items with a "Trailer" ribbon, using TMDB's
/videosendpoint for trailer resolution instead of a YouTube search. One full-width banner, one corner ribbon. - Show-level Maintainerr countdown for seasons. When a Maintainerr rule targets a show and its seasons are leaving, season posters now pick up the countdown from the show-level collection. Cherry-picked from b00pb0p's upstream PR #618.
- Log level setting. Configurable under Settings > General instead of needing an environment variable.
- Sync error badges. Collection cards show error and warning states so you can spot a broken sync without opening the detail.
- Poster editor font cap raised from 72px to 200px. (fork #56)
- Steady-state Plex write skipping. Sync checks whether a Plex write would change anything before making it, so a library that's already up to date doesn't generate unnecessary API calls.
Security
A full pass over every route that accepts user input. None of these are remotely exploitable on a typical home server behind a reverse proxy, but they close gaps that shouldn't be open regardless.
- Session authentication enforced on Trakt OAuth callback, all settings routes, and Plex settings mutation. Previously these relied on the frontend not exposing them.
- Path containment on placeholder file resolution and icon export, validated with
fs.realpath(). A crafted path could read or write outside the intended directories. - ZIP import expansion limits. Template imports now cap file count, total size, and individual file size.
- URL validation on collection preview and config save. Custom URLs are checked for scheme and destination.
- Download URL destination validation. User-supplied download URLs are checked against a localhost/private-range denylist.
A SECURITY.md is included for private vulnerability reports via GitHub's advisory flow.
Fixed
Person collection cleanup deleted every collection, every other sync
getPersonsAboveThreshold returned a list of qualifying person names. cleanupPersonCollections compared those against collection titles. The comparison never matched because the titles are templated ("Starring Tom Hanks") and the names are raw ("tom hanks"). Every managed person collection failed the check and was deleted on one sync, then recreated on the next. Matched the exact alternating pattern reported. Fixed by comparing against createPersonCollectionName() output. (upstream #619)
Random list configs got the same list
Multiple configs drawing from the same Letterboxd random-list pool picked independently with no cross-config exclusion. With 5 configs and a pool of 15 URLs, the birthday paradox made collision more likely than not. A per-sync exclusion set now tracks claimed URLs and falls back to reuse only when the pool is exhausted. (fork #55)
Visibility self-heal overwrote your settings on every sync
Discovery's self-heal assumed that identical active and inactive visibility was always corruption and reset both to all-true. A user who deliberately turned a collection off on Home (same visibility in both states) had it turned back on every sync. Removed the self-heal. If you were affected, re-set your visibility once after pulling; the old code already overwrote your saved config. (fork #51)
Log search crashed on deep objects
deepValueStrings() recursed without a depth limit. Nested log data (Plex metadata, overlay context) could blow the stack. Replaced with an iterative walk capped at 10 levels. (fork #58)
Poster preview blew out the modal
After the preview image loaded, its intrinsic 1000x1500 dimensions overrode the flex layout and pushed the overlay config list off-screen. Pinned to an explicit width. (fork #53)
Canvas border-box clipped overlay content
CSS border-box plus border-2 on the editor canvas wrapper ate 4px from the content area. At editor scale that's about 7 template pixels lost from the right and bottom edges. Switched to content-box. (fork #52)
Bulk edit table vanished in Firefox
Firefox's rendering of table-fixed with sticky positioning and a fixed width caused all table text to disappear. w-48 on the name column header was the trigger. Switched to min-w-48. (fork #54)
FlixPatrol platforms with dashed names returned no data
The platform name parser split subtypes at the first dash and treated everything after it as a content filter. For platforms like Viki TV (slug viki-tv) or Neon TV, this truncated the name and the heading match against the scraped page always failed. Replaced with a specific -kids suffix check, which is the only actual content filter. The hardcoded multi-part platform allowlist is gone. (fork #60)
Smaller fixes
- Quick sync no longer deletes work queue items on an unverified Plex add. The item stays queued until the add is confirmed. (fork #44)
collectionSortandtitleSortpropagate correctly fromfindExistingCollection, so an existing collection's sort order isn't silently dropped on sync.- The webhook scrobble prevention description in Settings was wrong. Fixed.
- Show preview no longer offers the estimated-date flag (shows never get one; it's a movie/season field).
- Overlay error details are visible in the completed state, so you can see what went wrong without tailing logs.
yt-dlpinstalls from Alpine's package registry instead of a pinned GitHub release, so trailer downloads get the current version on every build.
Known and unfixed
- Restoring a base poster larger than 1000x1500 downscales it. Movies and shows too, not just seasons.
- Restored posters stay locked in Plex.
- A targeted collection promoted to Home still shows on everyone's Home. Plex has no per-user version of that switch.
- Manual reorder resolves a multi-library config by its first library. Such a config can't be manually reordered in its second library.