gastownhall/beads · error

creating dolt directory: %w

Error message

creating dolt directory: %w

What it means

Returned by ensureDoltInit when os.MkdirAll cannot create the dolt database directory (config.BeadsDirPerm). bd needs this directory to hold the Dolt repository and compatibility marker; failure is always a wrapped filesystem error. Nothing else in ensureDoltInit runs when this fails.

Source

Thrown at internal/doltserver/doltserver.go:1931

	}
	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 {
		// .dolt/ exists — seed the marker if missing.
		// This is the non-destructive path: we just mark existing databases
		// as known. The destructive recovery path (RecoverPreV56DoltDir) is
		// triggered separately during version upgrades.
		_ = MarkDoltDirCompatible(doltDir)
		return nil // Already initialized
	}

	cmd := exec.Command("dolt", "init")
	cmd.Dir = doltDir
	if out, err := cmd.CombinedOutput(); err != nil {
		return fmt.Errorf("dolt init: %w\n%s", err, out)
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check what exists at the path: ls -la on the parent; if a regular file occupies the directory name, remove or rename it
  2. Fix ownership/permissions so the current user can create the directory, e.g. sudo chown $(whoami) <parent>
  3. Ensure the target filesystem is writable and has free space (df -h, mount)
  4. Verify the directory configured for bd storage (BD_DIR/HOME) points to a writable location

Example fix

// before (stale file blocks directory creation)
$ ls -la /path/.beads
-rw-r--r-- 1 user user 0 .beads
// after
$ rm /path/.beads   # or: mv /path/.beads /path/.beads.bak
$ bd ready          # ensureDoltInit creates .beads/ successfully
Defensive patterns

Strategy: validation

Validate before calling

parent := filepath.Dir(doltDir)
if info, err := os.Stat(doltDir); err == nil && !info.IsDir() {
    return fmt.Errorf("%s exists but is not a directory", doltDir)
}
if err := os.MkdirAll(doltDir, 0o755); err != nil {
    return fmt.Errorf("cannot create %s (check parent %s perms/space): %w", doltDir, parent, err)
}

Try / catch

if err := ensureDoltInit(doltDir); err != nil {
    var pathErr *fs.PathError
    if errors.As(err, &pathErr) && errors.Is(pathErr, os.ErrPermission) {
        return fmt.Errorf("fix permissions on %s: %w", filepath.Dir(doltDir), err)
    }
    return err
}

Prevention

When it happens

Trigger: ensureDoltInit is called with a doltDir path whose parent is unwritable, the path exists as a regular file (not a directory), or the filesystem is full/read-only — os.MkdirAll fails and the error is wrapped.

Common situations: BD_DIR / HOME pointing at an unwritable or read-only location; a stale file where the .beads directory should be; running bd as a different (unprivileged) user than the repo owner; disk quota exceeded.

Related errors


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