gastownhall/beads · error

failed to remove database: %w

Error message

failed to remove database: %w

What it means

For non-Dolt backends, option [2] deletes the SQLite-style database file with `os.Remove(dbPath)` (plus its `-wal`/`-shm` sidecars, whose errors are ignored). If removing the main database file fails for any reason other than 'does not exist', the error is wrapped as `failed to remove database: %w`. The reinitialize step is skipped so the old database is left intact.

Source

Thrown at cmd/bd/doctor/fix/repo_fingerprint.go:164

		confirm, err := repoFingerprintReadLine()
		if err != nil {
			return fmt.Errorf("failed to read confirmation: %w", err)
		}
		confirm = strings.TrimSpace(strings.ToLower(confirm))
		if confirm != "y" && confirm != "yes" {
			fmt.Println("  → Skipped (canceled)")
			return nil
		}

		// Remove database and reinitialize in-process
		fmt.Printf("  → Removing %s...\n", dbPath)
		if isDolt {
			if err := os.RemoveAll(dbPath); err != nil && !os.IsNotExist(err) {
				return fmt.Errorf("failed to remove Dolt database: %w", err)
			}
		} else {
			if err := os.Remove(dbPath); err != nil && !os.IsNotExist(err) {
				return fmt.Errorf("failed to remove database: %w", err)
			}
			_ = os.Remove(dbPath + "-wal")
			_ = os.Remove(dbPath + "-shm")
		}

		// Reinitialize by creating a new store (auto-bootstraps from JSONL)
		fmt.Println("  → Reinitializing database from JSONL...")
		ctx := context.Background()
		store, err := dolt.NewFromConfig(ctx, beadsDir)
		if err != nil {
			return fmt.Errorf("failed to initialize database: %w", err)
		}
		defer func() { _ = store.Close() }()

		fmt.Println("  ✓ Database reinitialized")
		return nil

	case "s", "":

View on GitHub (pinned to 71377f2769)

Solutions

  1. Stop processes using the file (`bd daemon --stop`; check with `lsof .beads/<dbfile>`) and retry the fix.
  2. Correct permissions/ownership of the `.beads` directory and database file.
  3. Verify the filesystem is not read-only and there is free disk space; move the workspace off problematic network mounts if needed.
  4. Inspect the unwrapped OS error (`errors.Unwrap`) to target the exact cause, or delete the file manually and re-bootstrap from `.beads/issues.jsonl`.

Example fix

# before
bd doctor --fix   # failed to remove database: permission denied
# after
sudo chown -R "$USER" .beads
bd daemon --stop
bd doctor --fix
Defensive patterns

Strategy: validation

Validate before calling

dbPath := filepath.Join(beadsDir, "dolt") // per configfile config
if handles := exec.Command("lsof", "+D", dbPath).Run(); handles == nil {
	return errors.New("database is open in another process; stop bd daemon first")
}
if info, err := os.Stat(beadsDir); err == nil && info.Mode().Perm()&0200 == 0 {
	return errors.New(".beads not writable by current user")
}

Try / catch

if err := fix.RepoFingerprint(path, true); err != nil && strings.Contains(err.Error(), "failed to remove Dolt database") {
	fmt.Fprintf(os.Stderr, "close other bd processes / fix permissions, then retry: %v\n", err)
	os.Exit(1)
}

Prevention

When it happens

Trigger: `os.Remove(dbPath)` returns a non-IsNotExist error on the configured database path: another process (bd daemon, SQLite client, IDE SQLite viewer) holds the file open in a way that blocks deletion, read-only filesystem, or insufficient write permission on `.beads`.

Common situations: bd daemon or another bd session keeping the SQLite DB open; database owned by a different user after running bd with sudo; database directory mounted read-only; backup/AV software holding a handle on the file (e.g. on network shares).

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/c8dcddf050874cd9. Report an issue: GitHub.