Changelog
Every change to how plungarr behaves or how it is configured, newest first. The date is the day the change reached the master branch, which also publishes the latest image.
2026-10-01
Episode titles Sonarr is still waiting for
- When your Sonarr file naming format includes the episode title, Sonarr holds back an episode whose title is still "TBA" or empty ("Episode has a TBA title and recently aired", or "Episode does not have a title and recently aired"). Sonarr retries the import every minute and imports the file once the title arrives, or once 48 hours have passed since the episode aired, whichever comes first. plungarr used to report these as an unrecognized block. It now recognizes them and leaves the import to Sonarr.
- The first time plungarr acts on one of these downloads, it asks Sonarr to refresh that series' metadata, once. A title that is already published upstream then arrives without waiting for Sonarr's own 12-hour series refresh. Logged as
REFRESHED. - plungarr reports the download only if it is still blocked an hour after the 48-hour window closes, because by then something else is holding it. It also reports one whose episode has no air date, since Sonarr then waits for a title with no time limit.
- A matched-by-ID download whose file carries the same rejection is no longer force-imported, because that would name the file "TBA". plungarr imports it once the rejection clears.
- No new settings. To stop Sonarr waiting for titles at all, set Episode Title Required to Never in Sonarr under Settings > Media Management > Importing (shown only with advanced settings on).
Changelog
RELEASE_NOTES.mdis now this dated changelog, also published on the project site.
2026-09-10
Leftover download folders
- New optional sweep for job folders in the download client's completed directory that nothing references any more. SABnzbd never deletes anything in its completed folder (by design, per its maintainers), and an arr only cleans up jobs it grabbed, so folders from deleted series, hand-added NZBs and failed orphans accumulate. One test system held 260 such folders, 89 GB, most of them empty
_FAILED_shells. - Enable it by mounting the completed folder into the container and setting
LEFTOVER_DIRSto the folders whose children are jobs, e.g./downloads/tv,/downloads/movies. A folder is a leftover when no configured arr queue item and no SAB queue or active-history job references its name, and neither it nor any file in it changed withinLEFTOVER_MIN_AGE_HOURS(default 24). Sweeps run everyLEFTOVER_HOURS(default 6). LEFTOVER_ACTIONdefaults tonotify: oneLEFTOVERline per folder with file count, size and last change, in the attention digest, reminded afterNOTIFY_REMIND_DAYS.deleteremoves the folder (needs a read-write mount), logged asLEFTOVER-DELETEDand counted in digests.- Safety: only real directories that are direct children of
LEFTOVER_DIRSare considered, symlinks and loose files are ignored, and any failed arr or SAB read (or a paused SAB queue) cancels the sweep. Dry run logs the intended deletions and never postpones the live sweep.
ntfy digests in parts
- ntfy digests longer than 4000 bytes are split at line boundaries into numbered parts ("plungarr daily (1/3)"). ntfy converts any message over 4096 bytes into an
attachment.txt, which is what a busy first day produced.
Nothing left to import
- A download blocked on a technicality ("matched by ID", "unable to determine if sample") whose folder is gone or holds no video is now handled like Sonarr's own "No files found are eligible" case: removed, blocklisted, and searched again. One whose files are all already in the library goes through
NOT_UPGRADE_ACTION. Previously both were reported every cycle and never cleared.
Folder-name mismatch imports tightened
- A folder-name mismatch is imported only when it looks like a parser quirk: the unexpected episodes Sonarr names are in another season, or there are more than five of them. A few unexpected episodes in the same season is what a genuinely mislabelled file looks like (a release folder that parsed as one episode holding a double episode), and that case is now reported instead of imported.
2026-09-09
Orphaned downloads
- A completed or failed download that no configured Sonarr/Radarr grabbed is now handled. This happens when a series or movie is deleted while its episodes are still downloading, or when an NZB is added to the client by hand. The arr lists it as an unknown item, nothing will ever import it, and it sits in the queue and on disk indefinitely.
ORPHAN_ACTION(defaultdelete) removes it from the arr queue and the download client, with no blocklist and no search.notifyonly reports it. Setnotifyif you add NZBs by hand and import them yourself.- Orphans wait for the normal age gate, and are never touched while another configured instance owns the same download, using the same paginated and unpaginated ownership checks as the stall watcher. If a sibling instance cannot be read, the orphan is left alone that cycle.
- Log line:
REMOVED (ORPHAN, no configured arr grabbed it), counted asorphanedin digests. - Sonarr and Radarr only read the most recent 60 entries of the download client's history. A large backlog of orphans hides older ones, and plungarr clears them a batch at a time as the arr exposes them.
Folder-name mismatches (Sonarr)
- Sonarr refuses to import a file whose parsed episode numbers disagree with the release folder name ("Episode 7x20 was unexpected considering the ... folder name"). In practice this is usually a parser quirk, such as
1x8_720.mkvreading as episode 7x20, and Sonarr's manual-import view still maps the file to the right episode. FOLDER_MISMATCH_ACTION(defaultimport) imports with Sonarr's own mapping, but only when every file maps to episodes the download was grabbed for and together they cover exactly those episodes. A file that maps outside the grab, or a set that does not cover it, is reported and left for a human.replace,discard, andnotifybehave as for the other block actions.
Multi-episode library files
- A single-episode download that would replace a library file spanning more episodes ("Episode file on disk contains more episodes than this file contains") is now treated as not an upgrade, so
NOT_UPGRADE_ACTIONapplies. Importing it would delete the other episodes' only copy.
Upgrade notes
- Two new settings default to acting:
ORPHAN_ACTION=deleteremoves completed or failed downloads that no configured arr grabbed, andFOLDER_MISMATCH_ACTION=importimports Sonarr folder-name mismatches with Sonarr's own mapping. Set either tonotifyto keep the previous behaviour of reporting only. - Configure every arr instance that shares the configured SAB instance before enabling the stall watcher or leaving
ORPHAN_ACTION=deleteon. A download one instance does not know about may belong to another.
2026-09-08
Project site
- The project site went live, with install steps, a generated settings reference, notifications, a comparison with similar tools, and an FAQ.
- plungarr is listed in Unraid Community Applications.
2026-09-07
Configurable block actions
- Four new settings decide what plungarr does with blocks it recognises but that need a policy choice:
ARCHIVE_ACTION(defaultreplace),DANGEROUS_FILE_ACTION(defaultreplace),SAMPLE_ACTION(defaultnotify), andNOT_UPGRADE_ACTION(defaultdiscard). Each takesreplace,discard, ornotify. Any other value stops startup naming the setting. - Not-an-upgrade rejections reported only on the manual-import candidates, not on the queue item, are now handled. Previously they were logged as an unexpected rejection and left in the queue indefinitely.
- Items in these classes always wait one cycle before plungarr acts, even when the arr reports them as import-blocked.
- The
REMOVED+RESEARCHlog label is nowREMOVED+REPLACE, and the loop-guard label readsno replacement search. Behaviour is unchanged.
Notifications
- Optional webhook delivery: set
NOTIFY_URLand pickNOTIFY_FORMAT(discord,slack,ntfy,gotify,apprise, or genericjson).NOTIFY_TOKENandNOTIFY_EXTRA_JSONcover receiver-specific auth and fields. EmptyNOTIFY_URLkeeps the previous log-only behaviour. - Seven categories each take
immediate,daily,weekly,monthly, ornone: attention and errors default to immediate, actions and problems to daily, corruption to weekly, summary and heartbeat to none. - Digest schedule via
NOTIFY_DIGEST_HOUR,NOTIFY_DIGEST_DAY, andNOTIFY_DIGEST_DAY_OF_MONTHin container local time. Unresolved attention items are re-sent afterNOTIFY_REMIND_DAYS. - Pending items and sent-times persist in the state file. Delivery failures are retried next cycle and never block queue processing. Dry run logs the digest text and never POSTs. A startup message validates the receiver.
- Invalid notification settings stop startup naming the setting.
- Attention items are not marked as sent while no receiver is configured, so they still go out once
NOTIFY_URLor the category is switched on. - A state file written by the first notifier build has its sent list cleared once. Deliveries log
NOTIFY-SENT. - The startup message and the heartbeat report whether the SABnzbd stall watcher is on.
Multiple Sonarr and Radarr instances
SONARR_2_URL/SONARR_2_API_KEY(and_3to_9, same forRADARR_) add further instances to one container. Optional_NAMElabels each one in logs, digests, and state. Duplicate names or a URL without a key stop startup naming the setting.- Configure every instance that shares a SABnzbd: the stall watcher only deletes a download as an orphan when no configured instance owns it.
Corruption review reporting
- Suspects are reported once per file, and again only if the file changes or after
NOTIFY_REMIND_DAYS. Entries for files that leave the library are forgotten automatically. CORRUPT_REPORT_CLASSES(defaultunreadable,stub,junk_readable) selects which classes are reported.tiny_readableandscanner_blindare opt-in because they are mostly legitimate shorts and unscanned containers.- Each report says what was seen and what it usually means, in plain words, with the file size.
- The sweep summary reports files checked, new suspects, previously reported, and suppressed counts.
Container user and state directory
- The image starts as root only to chown
/statetoPUID:PGID(default 99:100, Unraid's nobody:users) and then drops privileges via su-exec. Bind-mounted state folders created by Docker or Unraid are writable without manual intervention. SetPUID/PGIDto match your host convention. - The Unraid template prefills the SABnzbd URL with the standard port.
2026-09-05
First public release
- Library corruption review is report-only. Missing metadata, small files, unusual bitrate, and unknown file age never authorize deletion.
- Stall timers use continuous observations. Pause, displacement from the head, restart, invalid counters, failed reads, and monitoring gaps reset eligibility.
- Repair/checking/fetching states are protected. A fresh SAB check immediately before removal cancels actions when status, head position, or progress changes.
- Action caps limit removal attempts without skipping observations of other jobs.
- Complete arr and SAB queue reads detect incomplete and inconsistent pages. Potential orphans receive an additional unpaginated arr ownership check.
- Invalid numeric and boolean settings fail startup with the setting name.
- Dry runs use fresh memory-only state and never read or overwrite live state.
- One-shot runs await periodic reviews and persist their completed results.
- Tests run on branch pushes and pull requests, and image publication requires a passing test job. Action commits and the base image are pinned, with weekly dependency update proposals configured.
- Configuration examples and logs use generic placeholders and fictional data. Docker build contexts exclude environment files, state, tests, and Git history.
Upgrade notes
- The corruption sweep no longer deletes library files or searches for replacements. Remove obsolete corruption deletion/loop/age/pinned-series settings from your configuration. The supported settings are documented in
.env.example. - Missing-article thresholds remain configurable heuristics. Use
DRY_RUN=trueto inspect intended queue actions first.
Validation
- The regression suite covers destructive action decisions, pagination failures, state isolation, malformed configuration, and service startup against a local HTTP fixture. No real media service or library is needed. Run
node --testwith Node 22. Live integration testing and container vulnerability scanning remain separate release checks, and successful tests do not prove every deployment or upstream failure mode safe.