gastownhall/beads · error

cannot remove old dolt database at %s: %w Manually delete %

Error message

cannot remove old dolt database at %s: %w

Manually delete %s and retry

What it means

Returned by RecoverPreV56DoltDir when os.RemoveAll cannot delete the legacy .dolt/ directory detected as pre-0.56. The recovery path must delete the incompatible embedded-mode database and reinitialize, so a failed removal blocks recovery. The error explicitly tells the user to delete the directory manually and retry.

Source

Thrown at internal/doltserver/doltserver.go:1981

// The data is unrecoverable — the fix is to start fresh.
//
// Returns true if recovery was performed, false if not needed.
func RecoverPreV56DoltDir(doltDir string) (bool, error) {
	dotDolt := filepath.Join(doltDir, ".dolt")
	if _, err := os.Stat(dotDolt); os.IsNotExist(err) {
		return false, nil // No .dolt/ directory — nothing to recover
	}

	markerPath := filepath.Join(doltDir, bdDoltMarker)
	if _, err := os.Stat(markerPath); err == nil {
		return false, nil // Marker exists — database is from 0.56+
	}

	fmt.Fprintf(os.Stderr, "Detected dolt database from an older bd version (pre-0.56).\n")
	fmt.Fprintf(os.Stderr, "Rebuilding dolt database at %s ...\n", doltDir)

	if err := os.RemoveAll(dotDolt); err != nil {
		return false, fmt.Errorf("cannot remove old dolt database at %s: %w\n\n"+
			"Manually delete %s and retry", dotDolt, err, dotDolt)
	}

	// Reinitialize
	if err := ensureDoltInit(doltDir); err != nil {
		return true, fmt.Errorf("recovery: %w", err)
	}

	return true, nil
}

// IsPreV56DoltDir returns true if doltDir contains a .dolt/ directory that
// was NOT created by bd 0.56+ (missing .bd-dolt-ok marker). These databases
// were created by the old embedded Dolt mode and may be incompatible.
// Used by doctor checks to detect potentially problematic dolt databases.
func IsPreV56DoltDir(doltDir string) bool {
	dotDolt := filepath.Join(doltDir, ".dolt")
	if _, err := os.Stat(dotDolt); os.IsNotExist(err) {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Stop any other bd or dolt processes that may hold files open (pgrep dolt; pgrep bd), then retry the bd command
  2. Delete the directory manually as the error suggests: rm -rf <doltDir>/.dolt, using sudo if ownership differs
  3. Fix ownership: sudo chown -R $(whoami) <doltDir>/.dolt, then re-run bd
  4. Check for read-only mounts or immutable flags (mount | grep ro; chattr -i) if manual deletion also fails

Example fix

// before
# error: cannot remove old dolt database at /repo/.beads/.dolt: remove ...: permission denied
// after
$ sudo rm -rf /repo/.beads/.dolt
$ bd ready   # recovery reinitializes the database
Defensive patterns

Strategy: validation

Validate before calling

dotDolt := filepath.Join(doltDir, ".dolt")
if info, err := os.Stat(dotDolt); err == nil {
    // probe writability before destructive RemoveAll
    probe := filepath.Join(dotDolt, ".bd-probe")
    if f, err := os.OpenFile(probe, os.O_CREATE|os.O_WRONLY, 0600); err != nil {
        return fmt.Errorf("cannot modify %s (ownership/permissions); aborting recovery", dotDolt)
    } else {
        f.Close()
        os.Remove(probe)
    }
}

Try / catch

performed, err := RecoverPreV56DoltDir(doltDir)
if err != nil && strings.Contains(err.Error(), "cannot remove old dolt database") {
    var pathErr *fs.PathError
    if errors.As(err, &pathErr) && errors.Is(pathErr.Err, os.ErrPermission) {
        return fmt.Errorf("stop running bd/dolt processes and remove %s manually (sudo if needed)", pathErr.Path)
    }
    return err
}

Prevention

When it happens

Trigger: RecoverPreV56DoltDir detects .dolt/ without the .bd-dolt-ok marker (pre-0.56 database) during a version upgrade, calls os.RemoveAll(dotDolt), and it fails because a file/directory inside is unwritable, is owned by another user, or is held/open by another process.

Common situations: Pre-0.56 databases created by root or a different user (permission denied on delete); another bd/dolt process still running with open handles; immutable files or a read-only mount; syncing tools (IDE/Dropbox) locking files on some platforms.

Related errors


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