{"record":{"id":"b43381fd2eaa37f9","repo":"gastownhall/beads","slug":"backing-up-corrupt-dolt-database-at-s-w","errorCode":null,"errorMessage":"backing up corrupt dolt database at %s: %w","messagePattern":"backing up corrupt dolt database at (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/doltserver/manifest_recovery.go","lineNumber":237,"sourceCode":"\nfunc recoverCorruptManifest(beadsDir, doltDir string) ([]string, error) {\n\tnomsDirs, err := detectCorruptManifest(beadsDir, doltDir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(nomsDirs) == 0 {\n\t\treturn nil, nil\n\t}\n\n\tts := time.Now().UTC().Format(\"20060102T150405Z\")\n\tvar backups []string\n\tfor _, nomsDir := range nomsDirs {\n\t\tdotDolt := filepath.Dir(nomsDir) // .../X/.dolt\n\t\tdbDir := filepath.Dir(dotDolt)   // .../X\n\t\tbackupPath := dotDolt + \".\" + ts + \".corrupt.backup\"\n\n\t\tif err := os.Rename(dotDolt, backupPath); err != nil {\n\t\t\treturn backups, fmt.Errorf(\"backing up corrupt dolt database at %s: %w\", dotDolt, err)\n\t\t}\n\t\tbackups = append(backups, backupPath)\n\n\t\tif err := ensureDoltInit(dbDir); err != nil {\n\t\t\t// Best-effort restore so the user is no worse off than before.\n\t\t\t_ = os.RemoveAll(dotDolt)\n\t\t\t_ = os.Rename(backupPath, dotDolt)\n\t\t\treturn backups[:len(backups)-1], fmt.Errorf(\"reinitializing dolt database at %s: %w\", dbDir, err)\n\t\t}\n\t}\n\treturn backups, nil\n}\n","sourceCodeStart":219,"sourceCodeEnd":250,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/doltserver/manifest_recovery.go#L219-L250","documentation":"recoverCorruptManifest wraps os.Rename(dotDolt, backupPath) failures as \"backing up corrupt dolt database at %s: %w\". When bd detects a corrupt dolt manifest, it moves the entire .dolt directory aside (timestamped .corrupt.backup) before re-initializing; this error means the corrupt database could not be preserved, so recovery aborts rather than destroying data.","triggerScenarios":"A corrupt manifest signature is detected during server start, recoverCorruptManifest tries to rename the .dolt directory to .dolt.<ts>.corrupt.backup, and the rename fails: files inside are open/locked (another server or process holds them), permission problems, or cross-device paths.","commonSituations":"A second bd/dolt process is still running against the same workspace holding open file handles (especially on Windows where open files cannot be renamed); bd runs unprivileged while .dolt is root-owned; the workspace is on a network mount with locking issues.","solutions":["Stop all other dolt/bd processes using the workspace (check with lsof +D .dolt or handle.exe), then retry.","Fix ownership/permissions so the bd user can rename the .dolt directory.","Manually back up: cp -r X/.dolt X/.dolt.manual-backup, then remove the corrupt .dolt and let bd re-init.","Check the filesystem/mount health if rename fails with I/O errors."],"exampleFix":"// before (shell)\n$ bd start   # fails: backing up corrupt dolt database ...\n$ lsof +D myrepo/.dolt        # find the holder\n$ kill <pid>                  # stop the stale server\n// after\n$ bd start   # recovery proceeds: .dolt moved to .dolt.<ts>.corrupt.backup","handlingStrategy":"validation","validationCode":"// before attempting recovery, ensure nothing holds .dolt open\nout, _ := exec.Command(\"lsof\", \"+D\", dotDolt).Output()\nif len(bytes.TrimSpace(out)) > 0 {\n    return fmt.Errorf(\".dolt in use; stop other processes first\")\n}\nif info, err := os.Stat(dotDolt); err != nil || !info.IsDir() {\n    return fmt.Errorf(\".dolt missing or not a directory\")\n}","typeGuard":null,"tryCatchPattern":"backups, err := RecoverCorruptManifest(ws)\nif err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && errors.Is(pe.Err, syscall.EBUSY) {\n        return fmt.Errorf(\"another process holds .dolt open; stop it and retry: %w\", err)\n    }\n    return err\n}","preventionTips":["Stop all bd/dolt processes on the workspace before recovery","On Windows, ensure no handles are open in .dolt (open files cannot be renamed)","Keep .dolt and its backup target on the same filesystem","Run bd as a user with write permission on the workspace"],"tags":["filesystem","data-recovery","corruption","manifest","rename"],"backgroundTag":"corrupt-database-recovery-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}