gastownhall/beads · error

server: NewDoltServer: rootDir is required

Error message

server: NewDoltServer: rootDir is required

What it means

NewDoltServer requires a non-empty rootDir because all database files, config, and logs are resolved relative to it. An empty rootDir would point the backend at an invalid location, so the constructor rejects it immediately.

Source

Thrown at internal/storage/dbproxy/server/doltserver.go:68

	database        string
	config          servercfg.ServerConfig
	keepAlivePeriod time.Duration

	logFile *os.File
	eg      *errgroup.Group
	egCtx   context.Context
	cancel  context.CancelFunc
	pid     int
}

var _ DatabaseServer = (*DoltServer)(nil)

func NewDoltServer(doltBinExec, rootDir, configPath, logFilePath string, keepAlivePeriod time.Duration, database string) (*DoltServer, error) {
	if doltBinExec == "" {
		return nil, errors.New("server: NewDoltServer: doltBinExec is required")
	}
	if rootDir == "" {
		return nil, errors.New("server: NewDoltServer: rootDir is required")
	}
	if configPath == "" {
		return nil, errors.New("server: NewDoltServer: configPath is required")
	}
	absDoltBinExec, err := filepath.Abs(doltBinExec)
	if err != nil {
		return nil, errors.New("server: NewDoltServer: failed to determine absolute path of doltBinExec")
	}
	absRootDir, err := filepath.Abs(rootDir)
	if err != nil {
		return nil, errors.New("server: NewDoltServer: failed to determine absolute path of rootDir")
	}
	absConfigPath, err := filepath.Abs(configPath)
	if err != nil {
		return nil, errors.New("server: NewDoltServer: failed to determine absolute path of configPath")
	}
	cfg, err := servercfg.YamlConfigFromFile(filesys.LocalFS, configPath)
	if err != nil {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Pass the resolved workspace root directory to NewDoltServer
  2. Detect the root upstream (e.g. bd's workspace discovery) and fail fast with a clear message if absent
  3. Run from within an initialized workspace or create one before starting the server

Example fix

// before
srv, err := server.NewDoltServer(bin, rootDir, cfgPath, logPath, ka, db) // rootDir == ""
// after
if rootDir == "" {
    rootDir, err = workspace.FindRoot(cwd)
}
srv, err := server.NewDoltServer(bin, rootDir, cfgPath, logPath, ka, db)
Defensive patterns

Strategy: validation

Validate before calling

if rootDir == "" {
    return errors.New("workspace root not detected; run inside an initialized workspace")
}
srv, err := server.NewDoltServer(doltBin, rootDir, cfgPath, logPath, ka, db)

Try / catch

srv, err := server.NewDoltServer(doltBin, rootDir, cfgPath, logPath, ka, db)
if err != nil && strings.Contains(err.Error(), "rootDir is required") {
    return fmt.Errorf("could not determine workspace root: %w", err)
}

Prevention

When it happens

Trigger: Calling server.NewDoltServer(doltBin, "", ...) — rootDir not set in config or not derived from the workspace.

Common situations: Running outside a beads workspace so no root was detected; config field forgotten; programmatic callers passing empty strings as placeholders.

Related errors


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