Skip to content

DatabaseManager overwrites correctly-migrated settings with an empty default right after macOS migration succeeds #878

Description

@AgreeDK

Found while re-testing the #870 fix (v1.19.3) on real Mac hardware. This is a separate bug from #870 — the file-move issue #870 fixed is confirmed working correctly; this is a new issue surfaced immediately after.

Setup: Same reproduction as #870 — v1.18.0 with a custom-location database (Documents) plus the untouched default database, real username/home location entered, then upgraded directly to v1.19.3.

What the log shows (full opensak.log, settings_migration debug channel):

  1. migrate_macos_default_paths() runs, finds real data in the old directory, and successfully moves and verifies opensak.json (flyttede .../opensak.json (verificeret)) — confirming the Add a permanent, in-place backup of opensak.json before the macOS #825 migration touches it #870 fix works as intended.
  2. _rewrite_stale_install_dir_paths() opens the moved file, finds it contains the real settings (2 databases, real username), and correctly rewrites 1 stale path field (databases.list[0].path).
  3. Immediately after, DatabaseManager._load_from_settings() logs:
    _load_from_settings: databases.list=[], databases.active=None, databases.dir=None
    WARNING: Ingen kendte databaser fundet i settings (...) — opretter en frisk, tom 'Default'-database
    
  4. Checking opensak.json on disk immediately afterward shows it now contains only fresh, empty defaults — the real data (username, home location, both database entries) is gone.

Analysis:

_load_from_settings() calls _save_to_settings() unconditionally right after parsing (before the if not self._databases: fallback check):

# Gem migrerede stier tilbage (én gang)
self._save_to_settings()

# Hvis ingen databaser kendes, opret Default
if not self._databases:
    ...

If self._databases ends up empty at that point — for whatever reason store.get("databases.list", []) returned [] instead of the two real entries — this call persists that empty state straight back to opensak.json, permanently overwriting the correctly-migrated data that was on disk a moment earlier. The subsequent fallback-default logic then calls _save_to_settings() a second time, compounding it.

I could not reproduce the databases.list=[] read itself in isolation — a standalone Python reproduction of the exact same migrate_macos_default_paths()get_store()DatabaseManager() sequence, with the same data, correctly returns the real 2-entry list from store.get("databases.list"). This suggests the discrepancy is specific to the real, compiled/signed macOS app bundle rather than the settings-store logic itself — possibly something related to running from a notarized PyInstaller .app (in the same spirit as the already-documented Windows MSIX path-virtualization issue), though this is unconfirmed.

Suggested next steps:

  1. Make _save_to_settings() non-destructive when it has nothing meaningful to save — e.g. don't call it before the fallback-default block if self._databases is empty, since that write can only ever lose data at that specific point, never gain any. Move the initial _save_to_settings() call to after the fallback logic instead, so it's called exactly once, with the final, correct state.
  2. Add a debug line right at the top of _load_from_settings() printing id(store) and the raw store._data dict (not just the two keys), to determine whether this is the same SettingsStore singleton instance seeing empty data (a real read bug) versus a different instance entirely (a singleton/caching bug).
  3. Since I couldn't reproduce this outside the real app, next reproduction attempt should ideally run from source (python run.py) on the same Mac, not the compiled .app, to help isolate whether PyInstaller packaging/signing is a factor.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

OS: macbugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions