Summary
search_missing can permanently re-search the same MAX_CONCURRENT_SEARCHES items while items that have never been searched are never reached. It logs a normal success line every cycle, so it looks healthy the whole time.
In my case it re-searched the same 2 episodes 18 times in a row while 261 missing episodes had never been searched once.
Version: decluttarr v2.1.0 (commit dd474de), Sonarr 4.0.19.2979.
Cause
src/utils/wanted_manager.py::_get_arr_records sends sortKey but no sortDirection:
sort_key = f"{self.arr.detail_item_key}s.lastSearchTime"
params = {"page": "1", "pageSize": total_records_count, "sortKey": sort_key}
For this key the *arr API defaults to descending, so the list comes back most-recently-searched first, and items with lastSearchTime: null (never searched) sort last.
src/jobs/search_handler.py::_filter_wanted_items then takes from the top:
return items[: self.job.max_concurrent_searches]
So it selects the items it most recently searched, searches them again, and they stay at the head. The never-searched tail is unreachable.
Verified against a live Sonarr
Same endpoint, same sortKey, only sortDirection varies. First three lastSearchTime values:
DEFAULT (what decluttarr sends): ['2026-07-27T21:27:42Z', '2026-07-27T21:27:37Z', '2026-07-27T21:25:04Z']
&sortDirection=ascending: ['NEVER', 'NEVER', 'NEVER']
&sortDirection=descending: ['2026-07-27T21:27:42Z', '2026-07-27T21:27:37Z', '2026-07-27T21:25:04Z']
The default is descending, and ascending produces the order the code clearly intends.
Why MIN_DAYS_BETWEEN_SEARCHES=0 turns this into total starvation
_filter_recent_searches is the only thing that can evict the recently-searched head:
if last_time + timedelta(days=self.job.min_days_between_searches) < now:
With min_days_between_searches = 0 this is last_time < now, always true, so nothing is ever filtered. Combined with the descending order, the same top N are selected every single cycle, forever.
This makes 0 a genuine footgun. It reads like "no throttling, search freely", but its actual effect is "the backlog is permanently unreachable". Any non-zero value masks the sort bug, which is likely why this has gone unnoticed: the documented examples use 7.
Suggested fix
Request the direction explicitly:
params = {
"page": "1",
"pageSize": total_records_count,
"sortKey": sort_key,
"sortDirection": "ascending",
}
Least-recently-searched first, with never-searched items leading, which is what the job intends and makes it correct at any min_days_between_searches including 0.
Optionally also warn at startup when MIN_DAYS_BETWEEN_SEARCHES=0, since that currently disables the only protection against this.
Workaround for anyone hitting it
Set MIN_DAYS_BETWEEN_SEARCHES to any non-zero value. After changing 0 to 7, my next cycle immediately searched two episodes that had never been searched, and the never-searched count began falling for the first time.
Symptom to look for: the same titles in Job 'search_missing' triggered a search for N items cycle after cycle, while your *arr still reports a large missing count.
Thanks for decluttarr, it does a lot of quiet work here.
Summary
search_missingcan permanently re-search the sameMAX_CONCURRENT_SEARCHESitems while items that have never been searched are never reached. It logs a normal success line every cycle, so it looks healthy the whole time.In my case it re-searched the same 2 episodes 18 times in a row while 261 missing episodes had never been searched once.
Version: decluttarr
v2.1.0(commitdd474de), Sonarr4.0.19.2979.Cause
src/utils/wanted_manager.py::_get_arr_recordssendssortKeybut nosortDirection:For this key the *arr API defaults to descending, so the list comes back most-recently-searched first, and items with
lastSearchTime: null(never searched) sort last.src/jobs/search_handler.py::_filter_wanted_itemsthen takes from the top:So it selects the items it most recently searched, searches them again, and they stay at the head. The never-searched tail is unreachable.
Verified against a live Sonarr
Same endpoint, same
sortKey, onlysortDirectionvaries. First threelastSearchTimevalues:The default is descending, and
ascendingproduces the order the code clearly intends.Why
MIN_DAYS_BETWEEN_SEARCHES=0turns this into total starvation_filter_recent_searchesis the only thing that can evict the recently-searched head:With
min_days_between_searches = 0this islast_time < now, always true, so nothing is ever filtered. Combined with the descending order, the same top N are selected every single cycle, forever.This makes
0a genuine footgun. It reads like "no throttling, search freely", but its actual effect is "the backlog is permanently unreachable". Any non-zero value masks the sort bug, which is likely why this has gone unnoticed: the documented examples use7.Suggested fix
Request the direction explicitly:
Least-recently-searched first, with never-searched items leading, which is what the job intends and makes it correct at any
min_days_between_searchesincluding0.Optionally also warn at startup when
MIN_DAYS_BETWEEN_SEARCHES=0, since that currently disables the only protection against this.Workaround for anyone hitting it
Set
MIN_DAYS_BETWEEN_SEARCHESto any non-zero value. After changing0to7, my next cycle immediately searched two episodes that had never been searched, and the never-searched count began falling for the first time.Symptom to look for: the same titles in
Job 'search_missing' triggered a search for N itemscycle after cycle, while your *arr still reports a large missing count.Thanks for decluttarr, it does a lot of quiet work here.