gastownhall/beads · error
checking dolt compatibility marker %s: %w
Error message
checking dolt compatibility marker %s: %w
What it means
MarkDoltDirCompatible stats the compatibility marker <doltDir>/.bd-dolt-ok after confirming .dolt exists (internal/doltserver/doltserver.go:1918). If the marker is absent it is written; if os.Stat fails for a reason other than NotExist (permission denied, EIO, etc.) this error is returned. It is NOT the 'pre-0.56 incompatible database' case — that case returns a separate incompatibility error, not this one. The wrapped *PathError pinpoints why the marker path could not be examined.
Source
Thrown at internal/doltserver/doltserver.go:1918
// 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.
func ensureDoltInit(doltDir string) error {
if err := os.MkdirAll(doltDir, config.BeadsDirPerm); err != nil {
return fmt.Errorf("creating dolt directory: %w", err)
}
dotDolt := filepath.Join(doltDir, ".dolt")
if _, err := os.Stat(dotDolt); err == nil {View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped os.PathError — the errno (permission denied vs I/O error) tells you which branch to take.
- Fix ownership/permissions: `ls -ld <doltDir>` and `chown -R $USER <doltDir>` or `chmod u+rwx <doltDir>` if a prior sudo run claimed it.
- Check for immutable flags: `lsattr <doltDir>/.bd-dolt-ok` and `chattr -i` if set.
- If dmesg/filesystem logs show I/O errors, back up the data and check disk health (`smartctl`) before proceeding.
- Check audit logs for SELinux/AppArmor denials and adjust policy or move the data dir to an allowed path.
Example fix
// before: earlier sudo run left the dir root-owned $ ls -ld ~/.beads/dolt drwx------ 2 root root ... .beads/dolt // after $ sudo chown -R $USER:$USER ~/.beads/dolt $ bd ready # marker check succeeds
Defensive patterns
Strategy: validation
Validate before calling
// Verify the marker path is examinable before running bd
import ("os"; "path/filepath")
func markerAccessible(doltDir string) error {
if _, err := os.Stat(filepath.Join(doltDir, ".bd-dolt-ok")); err != nil {
if os.IsNotExist(err) { return nil } // absent is fine; bd will create it
return err
}
return nil
} Try / catch
// Go: unwrap the PathError to classify the failure
if err := MarkDoltDirCompatible(dir); err != nil && strings.HasPrefix(err.Error(), "checking dolt compatibility marker") {
var perr *os.PathError
if errors.As(err, &perr) {
switch {
case errors.Is(perr.Err, syscall.EACCES):
return fmt.Errorf("chmod/chown %s for the current user", dir)
case errors.Is(perr.Err, syscall.EIO):
return fmt.Errorf("disk I/O error on %s — check storage health", dir)
}
}
return err
} Prevention
- Never run bd with sudo; if you did, chown ~/.beads back to your user.
- Don't set immutable flags (chattr +i) on files inside the bd data directory.
- Monitor disk health on machines hosting Dolt data; investigate EIO in dmesg promptly.
- Keep the data directory on local, non-synced storage with stable permissions.
When it happens
Trigger: os.Stat on <doltDir>/.bd-dolt-ok fails with something other than ENOENT while MarkDoltDirCompatible runs from bd server/repair paths: no write/search permission on doltDir, immutable file attribute, failing disk (EIO), or a security policy (e.g. sandbox denying stat on dotfiles).
Common situations: dolt dir owned by another user after running bd with sudo once; chattr +i applied to the marker by an overzealous hardening script; failing SSD returning I/O errors; AppArmor/SELinux denials on the bd binary accessing the profile directory.
Related errors
- checking dolt metadata directory %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/d3b6df675d3ebff7.
Report an issue: GitHub.