fix(startup): a damaged database file at launch is replaced by an empty database without warning#1739

opened22d agobyMMatt Donovan

Note

Claude responding on behalf of Matt.

Defect: a damaged database file at launch is silently replaced by an empty one.

What: When the app starts and finds its database file empty, it treats the file as a brand new database and builds a fresh one in its place. The investigator sees an app with no Cases and no message saying anything went wrong. A file that is not a database at all stops the app from starting, with a general message that does not name the database. The app already has a check that tells a real database from a damaged one, and the restore path uses it. Startup does not.

This was split out of the restore-from-file defect during triage on 2026-10-04 by the maintainer's ruling. It was kept out of that fix because it changes the startup path, which the restore fix does not need.

Where it is, how to reproduce it, and the open question

Where: src/main/index.ts:479 calls initDatabase(join(userDataPath, 'birdbrain.db')) with no prior isIntactDatabase check. src/main/services/db/core.ts:26 skips the pre-migration snapshot when user_version is 0 and the schema is empty, then runMigrations builds a fresh schema. src/main/services/db/dbSnapshots.ts:288 (isIntactDatabase) is the existing probe; its docstring describes this outcome (#428 scenario B). Line numbers read at origin/main a35dd27f.

Reproduce: Quit the app, truncate birdbrain.db in the user data directory to zero bytes, launch. Expected today from the code: the app opens with no Cases and reports nothing. Not run by triage; the zero-length behavior of initDatabase was observed through the restore handler in #1700's reproduction.

Open question: a missing file is a legitimate first launch and must still create a database. The check has to tell "no file" from "a file that is present and not a database", and say what the investigator is shown and offered (restore a snapshot, restore a backup, quit) when it refuses.

Related: #1700. Its "database not intact" message cannot safely say "restart" until this is fixed.

Note

Claude responding on behalf of Matt.

This was generated by AI during triage.

Triage: needs a person

Category: bug, evidence-affecting Summary: At launch, a database file that is present but damaged must not be silently replaced by an empty database.

Why this cannot be handed to an agent yet: what the investigator sees and can do when the app refuses to open its database is a design decision. The app has no screen for it today, only a general "could not start" message.

Recommendation: when the file is present and fails the existing integrity check, do not migrate it. Show a dialog that says the database could not be read, leaves the file untouched, and offers to open the folder that holds the database snapshots, then quit. A missing file still starts fresh, as a first launch.

What the decision has to settle
  1. The dialog's wording and actions (open the snapshot folder, choose a backup to restore, quit).
  2. Whether the damaged file is kept in place or renamed aside before the app offers a fresh start.
  3. Whether this check also runs when a restore leaves the database unreadable, so #1700's "do not restart" message can change.

Labelled evidence-affecting during triage: the outcome destroys every Case, and src/main/index.ts and src/main/services/db/** are on the blocking tier.