gastownhall/beads · error
checking dolt metadata directory %s: %w
Error message
checking dolt metadata directory %s: %w
What it means
MarkDoltDirCompatible stats <doltDir>/.dolt to decide whether a local Dolt repository exists before writing the .bd-dolt-ok compatibility marker (internal/doltserver/doltserver.go:1910). A missing .dolt is a no-op success; this error is returned only when os.Stat fails for any other reason — permission denied, I/O error, too many symlinks, etc. The wrapped err is the raw *PathError, so the message includes the exact syscall failure.
Source
Thrown at internal/doltserver/doltserver.go:1910
// bdDoltMarker is written after a current bd process creates or acknowledges a
// local Dolt repository. Its absence in an existing .dolt/ directory indicates
// the database was created by a pre-0.56 bd version (which used embedded mode).
// Those databases are incompatible with the current server-only architecture.
const bdDoltMarker = ".bd-dolt-ok"
// MarkDoltDirCompatible writes the canonical bd compatibility marker when
// doltDir contains a local Dolt repository. It no-ops when there is no .dolt/
// directory, which lets server and repair paths call it defensively.
func MarkDoltDirCompatible(doltDir string) error {
if doltDir == "" {
return errors.New("dolt directory is required")
}
dotDolt := filepath.Join(doltDir, ".dolt")
if info, err := os.Stat(dotDolt); err != nil {
if os.IsNotExist(err) {
return nil
}
return fmt.Errorf("checking dolt metadata directory %s: %w", dotDolt, err)
} else if !info.IsDir() {
return fmt.Errorf("dolt metadata path %s is not a directory", dotDolt)
}
markerPath := filepath.Join(doltDir, bdDoltMarker)
if _, err := os.Stat(markerPath); err == nil {
return nil
} else if !os.IsNotExist(err) {
return fmt.Errorf("checking dolt compatibility marker %s: %w", markerPath, err)
}
if err := os.WriteFile(markerPath, []byte("ok\n"), 0600); err != nil {
return fmt.Errorf("writing dolt compatibility marker %s: %w", markerPath, err)
}
return nil
}
// ensureDoltInit initializes a dolt database directory if .dolt/ doesn't exist.
// If .dolt/ exists, seeds the .bd-dolt-ok marker for existing working databases.
// See GH#2137 for background on pre-0.56 database compatibility.View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped os.PathError — the syscall (stat) and errno (e.g. permission denied) identify the cause.
- Check permissions on the dolt dir and its parents: `ls -ld <doltDir> <doltDir>/.dolt` and each ancestor directory; fix with chmod/chown if bd runs as another user.
- If the path is on a network/removable volume, remount it and retry.
- If .dolt is a dangling symlink, remove it (`rm <doltDir>/.dolt`) so bd treats the dir as having no repo, then re-initialize.
- Run `bd doctor` to diagnose the state of the local dolt directory.
Example fix
// before: bd cannot stat .dolt because a backup tool replaced it with a dangling symlink $ ls -ld ~/.beads/dolt/.dolt lrwxr-xr-x 1 me me 20 ... .dolt -> /mnt/backup/.dolt (gone) // after $ rm ~/.beads/dolt/.dolt $ bd doctor # re-init or repair as advised
Defensive patterns
Strategy: validation
Validate before calling
// Validate the dolt dir is stat-able before invoking bd paths that call MarkDoltDirCompatible
import "os"
func checkDoltDir(doltDir string) error {
info, err := os.Stat(doltDir)
if err != nil { return err }
if !info.IsDir() { return fmt.Errorf("%s is not a directory", doltDir) }
if d := filepath.Join(doltDir, ".dolt"); doltExists(d) {
if _, err := os.Stat(d); err != nil { return err } // surfaces permission/EIO early
}
return nil
} Try / catch
// Go: distinguish permission problems from other failures and report the path
if err := MarkDoltDirCompatible(dir); err != nil && strings.HasPrefix(err.Error(), "checking dolt metadata directory") {
var perr *os.PathError
if errors.As(err, &perr) && errors.Is(perr.Err, syscall.EACCES) {
return fmt.Errorf("fix permissions on %s (run as the owning user)", dir)
}
return err
} Prevention
- Run bd consistently as one user; avoid sudo invocations that change ownership of ~/.beads.
- Keep Dolt data off network/synced mounts that can disappear or remount read-only.
- Never symlink .dolt to external locations; keep repository metadata in place.
- Run `bd doctor` periodically to catch permission/drive issues early.
When it happens
Trigger: Calling MarkDoltDirCompatible (directly or via bd server/repair paths) where <doltDir>/.dolt exists but cannot be stat'ed: parent directory lacks execute/search permission, the path traverses an unavailable NFS/network mount, .dolt is a broken symlink chain, or the filesystem returns EIO.
Common situations: Repository on a disconnected network drive; directory permissions changed by a sync/backup tool; .dolt replaced by a dangling symlink; running bd under a different user than the one who owns ~/.beads or the repo's dolt dir.
Related errors
- checking dolt compatibility marker %s: %w
- dolt path is not executable
- creating .bd-dolt-ok marker: %w
- failed to remove Dolt database: %w
- inspecting remote target %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/670b0789b6c6bb73.
Report an issue: GitHub.