From fb1cf53919d70603b464b00383ea0175efca68d1 Mon Sep 17 00:00:00 2001 From: JunghwanNA <70629228+shaun0927@users.noreply.github.com> Date: Thu, 16 Apr 2026 14:04:26 +0900 Subject: [PATCH] fix: harden repair backup scope and migrate swap rollback - repair.py: define backup_path before the conditional block so it is always in scope when the except handler references it - migrate.py: restore old palace from .old if both os.rename and shutil.move fail during the swap step --- mempalace/migrate.py | 7 +++++-- mempalace/repair.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mempalace/migrate.py b/mempalace/migrate.py index c804211..d56cc13 100644 --- a/mempalace/migrate.py +++ b/mempalace/migrate.py @@ -239,8 +239,11 @@ def migrate(palace_path: str, dry_run: bool = False, confirm: bool = False): try: os.rename(temp_palace, palace_path) except OSError: - # os.rename fails across filesystems; fall back to move - shutil.move(temp_palace, palace_path) + try: + shutil.move(temp_palace, palace_path) + except Exception: + os.rename(stale_path, palace_path) + raise shutil.rmtree(stale_path, ignore_errors=True) print("\n Migration complete.") diff --git a/mempalace/repair.py b/mempalace/repair.py index 1b4f271..d391d38 100644 --- a/mempalace/repair.py +++ b/mempalace/repair.py @@ -254,8 +254,8 @@ def rebuild_index(palace_path=None): # Back up ONLY the SQLite database, not the bloated HNSW files sqlite_path = os.path.join(palace_path, "chroma.sqlite3") + backup_path = sqlite_path + ".backup" if os.path.exists(sqlite_path): - backup_path = sqlite_path + ".backup" print(f" Backing up chroma.sqlite3 ({os.path.getsize(sqlite_path) / 1e6:.0f} MB)...") shutil.copy2(sqlite_path, backup_path) print(f" Backup: {backup_path}")