Review queue entries silently go stale and fail approval en masse #3

Closed
opened 2026-09-11 23:01:36 +08:00 by Breadway · 1 comment
Owner

Approving a review-queue entry returns an error (409/422) for almost every pending row, on a recurring basis (third time observed).

Root cause: eligibility ("is this episode/movie still missing/monitored?") is checked once when a low-confidence match is queued for review (scheduler.rs process_item), and again at approval time in prepare_review_approval (scheduler.rs:2257). Nothing re-checks or prunes a review_queue row in between. The search and upgrade cycles run continuously in the background and can satisfy an episode/movie via a different, higher-confidence release while a low-confidence entry for the same episode is still sitting pending. By the time a human reviews the queue (README recommends "check periodically", not every 30 min), most pending rows have gone stale and fail with NotMonitoredOrAlreadyHave (409) or CouldNotResolveEpisode (422) on approve.

No code path currently updates review_queue.status except the initial insert and the manual approve/reject/claim-release flow, so stale rows just accumulate silently until a human hits them.

Fix: add a periodic sweep (piggybacking on the existing hourly reconcile ticker in main.rs) that re-runs the same eligibility check against every pending row and marks newly-ineligible ones rejected with a stale_reason explaining why, so they stop silently rotting and failing on approval.

Approving a review-queue entry returns an error (409/422) for almost every pending row, on a recurring basis (third time observed). Root cause: eligibility ("is this episode/movie still missing/monitored?") is checked once when a low-confidence match is queued for review (`scheduler.rs` `process_item`), and again at approval time in `prepare_review_approval` (`scheduler.rs:2257`). Nothing re-checks or prunes a `review_queue` row in between. The search and upgrade cycles run continuously in the background and can satisfy an episode/movie via a different, higher-confidence release while a low-confidence entry for the same episode is still sitting pending. By the time a human reviews the queue (README recommends "check periodically", not every 30 min), most pending rows have gone stale and fail with `NotMonitoredOrAlreadyHave` (409) or `CouldNotResolveEpisode` (422) on approve. No code path currently updates `review_queue.status` except the initial insert and the manual approve/reject/claim-release flow, so stale rows just accumulate silently until a human hits them. Fix: add a periodic sweep (piggybacking on the existing hourly reconcile ticker in `main.rs`) that re-runs the same eligibility check against every pending row and marks newly-ineligible ones `rejected` with a `stale_reason` explaining why, so they stop silently rotting and failing on approval.
Author
Owner

Deployed to Hestia: merged #4, dev-release CI built and published 0.1.2-dev.20260911151548+4352253, bakery update breadarr installed it, breadarrd restarted clean and healthy (schema migration for stale_reason confirmed applied). The prune_stale_review_queue sweep runs on the hourly reconcile ticker, which is deliberately skipped at startup, so the first pass over the current 10 pending entries lands around 00:17 AWST.

Side finding while deploying: this repo's local CLAUDE.md claimed no CI existed here at all; that was stale. There's a real check/dev-release/rc-release/release pipeline on the self-hosted hestia runner, corrected the note. Also found check.yml's test job currently fails in CI (missing ffmpeg in that job's container, pre-existing, unrelated to this change), not filed as its own issue since it wasn't asked for, flagging here in case it's worth one.

Deployed to Hestia: merged #4, dev-release CI built and published 0.1.2-dev.20260911151548+4352253, bakery update breadarr installed it, breadarrd restarted clean and healthy (schema migration for stale_reason confirmed applied). The prune_stale_review_queue sweep runs on the hourly reconcile ticker, which is deliberately skipped at startup, so the first pass over the current 10 pending entries lands around 00:17 AWST. Side finding while deploying: this repo's local CLAUDE.md claimed no CI existed here at all; that was stale. There's a real check/dev-release/rc-release/release pipeline on the self-hosted hestia runner, corrected the note. Also found check.yml's test job currently fails in CI (missing ffmpeg in that job's container, pre-existing, unrelated to this change), not filed as its own issue since it wasn't asked for, flagging here in case it's worth one.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Breadway/breadarr#3
No description provided.