From ec518d4758a0d84bb7279d4dee584fd72c8daeae Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Sun, 19 Jul 2026 17:00:15 -0400 Subject: [PATCH] Prune stale chronic failure counts once an item stops being a problem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FAILURE_COUNTS persisted across runs but was never reset on success — confirmed live 2026-07-19 that Sekirei S06E04 sat permanently flagged chronic at count 4 despite already having hasFile=true. "Consecutive failures" was really being measured as cumulative-for-all-time. Now prunes any media_id's count at the end of each arr's pass if it no longer appears in that run's problem-item set, so a resolved item's history doesn't linger and falsely trip the circuit breaker later. --- Arrs_Stack/arrs_failed_stalled_recovery.sh | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Arrs_Stack/arrs_failed_stalled_recovery.sh b/Arrs_Stack/arrs_failed_stalled_recovery.sh index 8655e2c..6a883fd 100755 --- a/Arrs_Stack/arrs_failed_stalled_recovery.sh +++ b/Arrs_Stack/arrs_failed_stalled_recovery.sh @@ -74,6 +74,12 @@ # but search is no longer auto-triggered — it's flagged chronic and left for # manual review instead. # +# "Consecutive" is enforced, not just counted — a media_id's failure count +# is pruned at the end of every process_arr() pass if it no longer appears +# in that run's problem-item set (2026-07-19 fix: counts were never reset on +# success, so an item that failed a few times months apart and then imported +# fine could still get stuck permanently chronic from stale history). +# # ============================================================================================== # OPERATIONAL SAFEGUARDS # ============================================================================================== @@ -486,6 +492,9 @@ process_arr() { local actioned=0 skipped_new=0 chronic=0 smart_imported=0 local is_chronic fail_key fail_count + local -A seen_media_ids # media_ids appearing as a problem this run — anything NOT in + # here by the end has stopped being a problem and has its + # FAILURE_COUNTS entry pruned below echo "" echo "━━━ $ICON_SYNC $arr_name ━━━" @@ -593,6 +602,8 @@ process_arr() { lidarr) media_id=$(echo "$item" | jq -r '.albumId // .album.id // empty' 2>/dev/null) ;; esac + [[ -n "$media_id" ]] && seen_media_ids["$media_id"]=1 + [[ -z "$queue_id" ]] && continue # Age check — skip items that are too new to have self-resolved @@ -668,6 +679,21 @@ process_arr() { done <<< "$problem_items" + # Prune stale failure counts — anything for this arr_type that isn't a problem in this + # run's queue snapshot has either imported successfully or is otherwise no longer stuck. + # FAILURE_COUNTS never decremented on success (confirmed live 2026-07-19: Sekirei S06E04 + # sat chronic at count 4 despite hasFile=true, already fully resolved) — "consecutive + # failures" is supposed to mean consecutive since it last wasn't a problem, not a + # cumulative count for all time. Age-skipped items are still in seen_media_ids (added + # before the age check above), so a too-new item correctly keeps its count instead of + # being reset just for not having been acted on yet. + local _fc_key _fc_id + for _fc_key in "${!FAILURE_COUNTS[@]}"; do + [[ "$_fc_key" == "${arr_type}:"* ]] || continue + _fc_id="${_fc_key#${arr_type}:}" + [[ -z "${seen_media_ids[$_fc_id]:-}" ]] && unset "FAILURE_COUNTS[$_fc_key]" + done + if [[ "$actioned" -gt 0 ]]; then warn "$arr_name — actioned: $actioned (smart-imported: $smart_imported) | skipped (too new): $skipped_new | chronic: $chronic" else