Description
Tautulli.get_activity() (app/modules/tautulli.py) returns an empty dict on any empty fetch, with no sanity check. Downstream, an empty activity dict makes find_watched_data return None for every item, which bypasses both last_watched_threshold and the recently-watched protection in check_watched_status (app/media_cleaner.py).
With a common config (watch_status: unwatched, or a bare last_watched_threshold), that turns EVERY item in the library into an actionable deletion candidate - up to max_actions_per_run recently-watched titles get deleted, silently, on a single bad run.
Failure Scenario
Tautulli is reachable but returns empty or partial history: database rebuild in progress, section ID mismatch after a Plex library re-add, auth quietly returning an empty set. Deleterr interprets "no watch data" as "nothing was ever watched" and deletes accordingly. This is the worst failure class for a deletion tool: irreversible, silent, and triggered by a dependency being degraded rather than down.
Proposed Fix
- Treat zero or near-zero activity as suspicious: abort a library's deletions when watch activity is empty, or dramatically below the previous run's count (persist the last count in the state file)
- Distinguish "genuinely empty history" from "fetch returned nothing" and fail safe on the latter
- Log the abort loudly and send a failure notification
- Add regression tests asserting empty activity yields ZERO deletions
Description
Tautulli.get_activity()(app/modules/tautulli.py) returns an empty dict on any empty fetch, with no sanity check. Downstream, an empty activity dict makesfind_watched_datareturnNonefor every item, which bypasses bothlast_watched_thresholdand the recently-watched protection incheck_watched_status(app/media_cleaner.py).With a common config (
watch_status: unwatched, or a barelast_watched_threshold), that turns EVERY item in the library into an actionable deletion candidate - up tomax_actions_per_runrecently-watched titles get deleted, silently, on a single bad run.Failure Scenario
Tautulli is reachable but returns empty or partial history: database rebuild in progress, section ID mismatch after a Plex library re-add, auth quietly returning an empty set. Deleterr interprets "no watch data" as "nothing was ever watched" and deletes accordingly. This is the worst failure class for a deletion tool: irreversible, silent, and triggered by a dependency being degraded rather than down.
Proposed Fix