ADR-0009: Detect Cleanuparr Seeker and warn about double searching¶
- Status: superseded by ADR-0012 (2026-10-17)
- Date: 2026-10-16
- Supersedes: ADR-0007, its "There is no Seeker detection" bullet only. The read-only link and strike handling stand.
Context¶
Cleanuparr ships Seeker, a background job that searches *arr instances for missing and cutoff-unmet items. Upstream Cleanuparr (v2.10.11, commit 9f324ead) implements it for Sonarr and Radarr only:
code/backend/Cleanuparr.Infrastructure/Features/Jobs/Seeker.cs(the job; skips search commands under global dry run)code/backend/Cleanuparr.Api/Features/Seeker/Controllers/SeekerConfigController.cs(GET /api/configuration/seeker)code/backend/Cleanuparr.Api/Features/Arr/Controllers/ArrConfigController.cs(GET /api/configuration/{sonarr,radarr})code/backend/Cleanuparr.Persistence/Models/Configuration/General/GeneralConfig.cs(DryRun)code/backend/Cleanuparr.Api/DependencyInjection/AuthDI.cs(requests withX-Api-Keyuse the API key scheme)
When Seeker's proactive search is active on the same Sonarr or Radarr library that SnatchArr is searching, both tools issue search commands for missing and upgrade items. This duplicates queries to indexers, consumes download client capacity, and risks rate-limit strikes or bans from indexers.
ADR-0007 originally noted that there was no Seeker detection, relying on afterglow to absorb searches following item removal. While afterglow handles replacement searches when Cleanuparr strikes and re-searches a single removed item, it does not prevent continuous duplicate searches when Seeker's proactive routine runs across the whole library.
Decision¶
- Read-only inspection: SnatchArr checks Seeker configuration using the existing credentials of each linked Cleanuparr instance (
GET /api/configuration/seeker,GET /api/configuration/general,GET /api/configuration/sonarr,GET /api/configuration/radarr). SnatchArr never writes to Cleanuparr or changes any setting there. - Strict allow-list for sensitive fields: Cleanuparr's
/api/configuration/{type}response records carry anapiKeyproperty (masked bySensitiveDataResolver). SnatchArr uses a strict allow-list parser that decodes onlyid,name,url, andenabled. Cleanuparr's instanceapiKeyis never deserialized, retained in memory, logged, or returned by the API. - Activity criteria: Seeker is considered active for a library only when all five conditions hold:
searchEnabledis true in Seeker configuration,proactiveSearchEnabledis true in Seeker configuration,instance.enabledis true for that Seeker instance,instance.arrInstanceEnabledis true, andgeneral.dryRunis false (global dry run prevents Seeker from dispatching searches). Replacement-only search (proactiveSearchEnabled == false) does not warn, as afterglow already absorbs strike replacements.- Normalised URL matching: Seeker instances are mapped to base URLs via
arrInstanceIdlookups against the Sonarr/Radarr configuration endpoints. Matching between a Cleanuparr Seeker instance and a SnatchArr instance is performed strictly by normalised base URL (scheme, lowercase host, default ports:80/:443stripped, trailing slashes removed). There is no fallback to name-based matching. - Supported kinds: Cleanuparr Seeker only manages Sonarr and Radarr. Lidarr and Readarr instances in SnatchArr are never flagged as overlapping.
- Fail-open behaviour: If Cleanuparr is unreachable or returns HTTP 404 on
/api/configuration/seeker(such as on older Cleanuparr releases before Seeker existed), Seeker state is reported asunknownwith the reason, and no warnings are generated. When the Sonarr or Radarr configuration cannot be read, the state stays as computed,reasonnames the failed lookup, and the affected instances are reported unmatched. - Additive API schema:
GET /api/v1/cleanuparr/statusincludes aseekerobject with overall state (active,inactive,dry_run,unknown), optionalreason, and the list of observed Seeker instances with their match status.- The
Instanceschema gains an optionalseeker_overlap: boolproperty indicating whether an active Seeker instance targets the same library URL. - Web UI notifications:
- The instances table displays a badge on overlapping instances.
- The instance detail view displays a warning banner explaining that both tools search the same library and that running both risks rate limits.
- When overlapping and enabled, the banner includes a "Pause SnatchArr for this instance" button using the existing
PUT /instances/{id}endpoint (enabled: false) with an in-page confirmation step. - The Cleanuparr status page lists the observed Seeker configuration and instance matches per link.
Consequences¶
- Operators are warned before indexer limits or stamina budgets are doubled by overlapping proactive searches.
- The user can pause SnatchArr for the overlapping library with a single click, or disable Seeker in Cleanuparr.
- Older Cleanuparr versions without Seeker continue working without spurious errors or warnings.
- The separation of responsibilities remains intact: Cleanuparr manages download health, SnatchArr manages snatches, and SnatchArr remains entirely read-only toward Cleanuparr.