From f528a16065a259dd7c5cce09725d7ae7a0381457 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 16 Mar 2026 04:58:47 +0000 Subject: [PATCH] fix: clean up stale DB recording entries when file is missing on disk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When reduce_storage_consumption() encountered a FileNotFoundError (file deleted outside Frigate), it silently skipped the recording without removing it from the database. Over time this caused the DB to accumulate stale entries, making "Frigate recordings tracked" in /system#storage dramatically overstate actual disk usage. The bug also affected cleanup behaviour: stale entries don't count toward freed-space accounting, so Phase 2 (force-delete retained recordings) could trigger prematurely when most old entries were stale. Fix: always append the recording to deleted_recordings regardless of whether the file existed, so the DB entry is removed. freed-space accounting is unchanged — FileNotFoundError still does not increment deleted_segments_size since no actual disk space was recovered. Applied to both Phase 1 (non-retained) and Phase 2 (retained) loops inside reduce_storage_consumption(). https://claude.ai/code/session_01DMdSSQhQfTuXmzPtRvJmLB --- frigate/storage.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frigate/storage.py b/frigate/storage.py index 9bcec9c4c..1e6c0ca88 100644 --- a/frigate/storage.py +++ b/frigate/storage.py @@ -304,11 +304,12 @@ class StorageMaintainer(threading.Thread): if not keep: try: clear_and_unlink(Path(recording.path), missing_ok=False) - deleted_recordings.append(recording) deleted_segments_size += recording.segment_size except FileNotFoundError: - # this file was not found so we must assume no space was cleaned up + # File is missing from disk but the DB entry is stale; remove it + # without counting freed space since nothing was actually freed. pass + deleted_recordings.append(recording) # check if need to delete retained segments if deleted_segments_size < hourly_bandwidth: @@ -337,10 +338,11 @@ class StorageMaintainer(threading.Thread): try: clear_and_unlink(Path(recording.path), missing_ok=False) deleted_segments_size += recording.segment_size - deleted_recordings.append(recording) except FileNotFoundError: - # this file was not found so we must assume no space was cleaned up + # File is missing from disk but the DB entry is stale; remove it + # without counting freed space since nothing was actually freed. pass + deleted_recordings.append(recording) else: logger.info(f"Cleaned up {deleted_segments_size} MB of recordings")