{"record":{"id":"7f86250efc398575","repo":"gastownhall/beads","slug":"cannot-remove-old-dolt-database-at-s-w-manuall","errorCode":null,"errorMessage":"cannot remove old dolt database at %s: %w\n\nManually delete %s and retry","messagePattern":"cannot remove old dolt database at (.+?): %w\n\nManually delete (.+?) and retry","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/doltserver/doltserver.go","lineNumber":1981,"sourceCode":"// The data is unrecoverable — the fix is to start fresh.\n//\n// Returns true if recovery was performed, false if not needed.\nfunc RecoverPreV56DoltDir(doltDir string) (bool, error) {\n\tdotDolt := filepath.Join(doltDir, \".dolt\")\n\tif _, err := os.Stat(dotDolt); os.IsNotExist(err) {\n\t\treturn false, nil // No .dolt/ directory — nothing to recover\n\t}\n\n\tmarkerPath := filepath.Join(doltDir, bdDoltMarker)\n\tif _, err := os.Stat(markerPath); err == nil {\n\t\treturn false, nil // Marker exists — database is from 0.56+\n\t}\n\n\tfmt.Fprintf(os.Stderr, \"Detected dolt database from an older bd version (pre-0.56).\\n\")\n\tfmt.Fprintf(os.Stderr, \"Rebuilding dolt database at %s ...\\n\", doltDir)\n\n\tif err := os.RemoveAll(dotDolt); err != nil {\n\t\treturn false, fmt.Errorf(\"cannot remove old dolt database at %s: %w\\n\\n\"+\n\t\t\t\"Manually delete %s and retry\", dotDolt, err, dotDolt)\n\t}\n\n\t// Reinitialize\n\tif err := ensureDoltInit(doltDir); err != nil {\n\t\treturn true, fmt.Errorf(\"recovery: %w\", err)\n\t}\n\n\treturn true, nil\n}\n\n// IsPreV56DoltDir returns true if doltDir contains a .dolt/ directory that\n// was NOT created by bd 0.56+ (missing .bd-dolt-ok marker). These databases\n// were created by the old embedded Dolt mode and may be incompatible.\n// Used by doctor checks to detect potentially problematic dolt databases.\nfunc IsPreV56DoltDir(doltDir string) bool {\n\tdotDolt := filepath.Join(doltDir, \".dolt\")\n\tif _, err := os.Stat(dotDolt); os.IsNotExist(err) {","sourceCodeStart":1963,"sourceCodeEnd":1999,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/doltserver/doltserver.go#L1963-L1999","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Stop any other bd or dolt processes that may hold files open (pgrep dolt; pgrep bd), then retry the bd command","Delete the directory manually as the error suggests: rm -rf <doltDir>/.dolt, using sudo if ownership differs","Fix ownership: sudo chown -R $(whoami) <doltDir>/.dolt, then re-run bd","Check for read-only mounts or immutable flags (mount | grep ro; chattr -i) if manual deletion also fails"],"exampleFix":"// before\n# error: cannot remove old dolt database at /repo/.beads/.dolt: remove ...: permission denied\n// after\n$ sudo rm -rf /repo/.beads/.dolt\n$ bd ready   # recovery reinitializes the database","handlingStrategy":"validation","validationCode":"dotDolt := filepath.Join(doltDir, \".dolt\")\nif info, err := os.Stat(dotDolt); err == nil {\n    // probe writability before destructive RemoveAll\n    probe := filepath.Join(dotDolt, \".bd-probe\")\n    if f, err := os.OpenFile(probe, os.O_CREATE|os.O_WRONLY, 0600); err != nil {\n        return fmt.Errorf(\"cannot modify %s (ownership/permissions); aborting recovery\", dotDolt)\n    } else {\n        f.Close()\n        os.Remove(probe)\n    }\n}","typeGuard":null,"tryCatchPattern":"performed, err := RecoverPreV56DoltDir(doltDir)\nif err != nil && strings.Contains(err.Error(), \"cannot remove old dolt database\") {\n    var pathErr *fs.PathError\n    if errors.As(err, &pathErr) && errors.Is(pathErr.Err, os.ErrPermission) {\n        return fmt.Errorf(\"stop running bd/dolt processes and remove %s manually (sudo if needed)\", pathErr.Path)\n    }\n    return err\n}","preventionTips":["Stop all bd/dolt processes before upgrading bd versions","Ensure .beads ownership matches the user performing the upgrade","Do not place .beads on read-only or externally synced mounts","Back up .beads before version upgrades, though pre-0.56 data is unrecoverable"],"tags":["filesystem","permissions","dolt","recovery","data-migration"],"backgroundTag":"dolt-legacy-db-removal-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}