From fc99b549ee50410196aea48d61f5954acfae7583 Mon Sep 17 00:00:00 2001 From: Jasmine Naderi Date: Wed, 22 Jul 2026 20:07:29 -0400 Subject: [PATCH] =?UTF-8?q?fix(backup):=20skip=20prune=20when=20DB=20captu?= =?UTF-8?q?re=20failed=20=E2=80=94=20preserve=20recovery=20source?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address #68805 review: when failed_dbs is non-empty, skip _prune_quick_snapshots so the incomplete snapshot does not delete the older snapshot containing the last good database. The updater's keep=1 would otherwise evict the recovery source. --- hermes_cli/backup.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/hermes_cli/backup.py b/hermes_cli/backup.py index 65aacaab39827..bcbd01e83ff94 100644 --- a/hermes_cli/backup.py +++ b/hermes_cli/backup.py @@ -1177,7 +1177,18 @@ def create_quick_snapshot( # Auto-prune. Defaults preserve historical manual /snapshot behavior; callers # with known high-churn safety snapshots (for example pre-update) can pass a # smaller keep value so large state.db copies do not accumulate indefinitely. - _prune_quick_snapshots(root, keep=_QUICK_DEFAULT_KEEP if keep is None else keep) + # #68805 review: skip pruning when a present DB failed to capture — the + # incomplete snapshot must not delete the older snapshot that may contain + # the last good database (the recovery source this hardening is meant to + # preserve). + if not failed_dbs: + _prune_quick_snapshots(root, keep=_QUICK_DEFAULT_KEEP if keep is None else keep) + else: + logger.warning( + "Skipping snapshot prune because %d DB(s) failed to capture — " + "preserving older snapshots as recovery source", + len(failed_dbs), + ) logger.info("State snapshot created: %s (%d files)", snap_id, len(manifest)) return snap_id