Skip to content

[Bug] Fix remove_orphans deleting active downloads (#322) - #385

Merged
lolimmlost merged 1 commit into
ManiMatter:devfrom
keez97:fix/orphans-compare-by-id
Sep 24, 2026
Merged

lolimmlost merged 1 commit into
ManiMatter:devfrom
keez97:fix/orphans-compare-by-id

Conversation

@keez97

@keez97 keez97 commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Fixes #322.

get_queue_items("orphans") computed orphans as [fq for fq in full_queue if fq not in normal_queue], comparing whole records. The two fetches are separate requests after a RefreshMonitoredDownloads, so sizeleft / timeleft / estimatedCompletionTime of an actively downloading item differ between them. The record comparison then fails and the download is treated as an orphan and removed (without blocklist, since RemoveOrphans.blocklist = False). Paused and stalled items never change between the fetches, which is why only healthy downloads were hit.

Change: compare by queue item id instead of by record.

  • src/utils/queue_manager.py: build a set of ids from the normal queue and keep full-queue items whose id is not in it
  • tests/utils/test_queue_manager.py: regression test where the same item has a different sizeleft in the two fetches; fails on the old code, passes on the new

Full suite: 293 passed.

Verified on my Radarr/Sonarr + qBittorrent stack: the old image deleted three actively downloading remuxes over two days; the patched image ran three 5-minute cycles against a download progressing at ~3 MB/s with no removal.

- compare the full and normal queue by item id instead of whole records; sizeleft/timeleft of an active download change between the two fetches, so any progressing download was flagged as an orphan and deleted (ManiMatter#322)
- regression test

@lolimmlost lolimmlost left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed and tested locally. LGTM.

The root cause matches the analysis in #322: the full and normal queue fetches are separate requests, so progress fields (sizeleft, timeleft, estimatedCompletionTime) on an active download differ between them and the whole-record not in check flags it as an orphan. Comparing by queue item id is the right fix, since the *arr queue id is derived from the download and the media item and is stable across back-to-back fetches.

Verified:

  • Full test suite passes (293 passed).
  • The new regression test fails against current dev (1 failed) and passes with the fix, so it actually covers the bug.
  • This was the only place in src/ doing a whole-record queue comparison, so there are no other instances of the same pattern.
  • If an item were ever missing id, None matches None and it is not treated as an orphan, which fails safe (no deletion).

Nit (non-blocking): there are 3 blank lines before the new test in tests/utils/test_queue_manager.py; PEP 8 / ruff E303 wants 2.

@ManiMatter

Copy link
Copy Markdown
Owner

@lolimmlost feel free to directly merge any PRs you approve. Full trust :)

@lolimmlost
lolimmlost merged commit ed30b9a into ManiMatter:dev Sep 24, 2026
4 checks passed
@keez97
keez97 deleted the fix/orphans-compare-by-id branch September 24, 2026 22:57
@keez97
keez97 restored the fix/orphans-compare-by-id branch September 24, 2026 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

REMOVE_ORPHANS deletes valid downloads immediately upon completion (Race Condition?)

3 participants