{"record":{"id":"3a7a7e1ecb821c76","repo":"gastownhall/beads","slug":"server-newdoltserver-rootdir-is-required","errorCode":null,"errorMessage":"server: NewDoltServer: rootDir is required","messagePattern":"server: NewDoltServer: rootDir is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/server/doltserver.go","lineNumber":68,"sourceCode":"\tdatabase        string\n\tconfig          servercfg.ServerConfig\n\tkeepAlivePeriod time.Duration\n\n\tlogFile *os.File\n\teg      *errgroup.Group\n\tegCtx   context.Context\n\tcancel  context.CancelFunc\n\tpid     int\n}\n\nvar _ DatabaseServer = (*DoltServer)(nil)\n\nfunc NewDoltServer(doltBinExec, rootDir, configPath, logFilePath string, keepAlivePeriod time.Duration, database string) (*DoltServer, error) {\n\tif doltBinExec == \"\" {\n\t\treturn nil, errors.New(\"server: NewDoltServer: doltBinExec is required\")\n\t}\n\tif rootDir == \"\" {\n\t\treturn nil, errors.New(\"server: NewDoltServer: rootDir is required\")\n\t}\n\tif configPath == \"\" {\n\t\treturn nil, errors.New(\"server: NewDoltServer: configPath is required\")\n\t}\n\tabsDoltBinExec, err := filepath.Abs(doltBinExec)\n\tif err != nil {\n\t\treturn nil, errors.New(\"server: NewDoltServer: failed to determine absolute path of doltBinExec\")\n\t}\n\tabsRootDir, err := filepath.Abs(rootDir)\n\tif err != nil {\n\t\treturn nil, errors.New(\"server: NewDoltServer: failed to determine absolute path of rootDir\")\n\t}\n\tabsConfigPath, err := filepath.Abs(configPath)\n\tif err != nil {\n\t\treturn nil, errors.New(\"server: NewDoltServer: failed to determine absolute path of configPath\")\n\t}\n\tcfg, err := servercfg.YamlConfigFromFile(filesys.LocalFS, configPath)\n\tif err != nil {","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/server/doltserver.go#L50-L86","documentation":"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.","triggerScenarios":"Calling server.NewDoltServer(doltBin, \"\", ...) — rootDir not set in config or not derived from the workspace.","commonSituations":"Running outside a beads workspace so no root was detected; config field forgotten; programmatic callers passing empty strings as placeholders.","solutions":["Pass the resolved workspace root directory to NewDoltServer","Detect the root upstream (e.g. bd's workspace discovery) and fail fast with a clear message if absent","Run from within an initialized workspace or create one before starting the server"],"exampleFix":"// before\nsrv, err := server.NewDoltServer(bin, rootDir, cfgPath, logPath, ka, db) // rootDir == \"\"\n// after\nif rootDir == \"\" {\n    rootDir, err = workspace.FindRoot(cwd)\n}\nsrv, err := server.NewDoltServer(bin, rootDir, cfgPath, logPath, ka, db)","handlingStrategy":"validation","validationCode":"if rootDir == \"\" {\n    return errors.New(\"workspace root not detected; run inside an initialized workspace\")\n}\nsrv, err := server.NewDoltServer(doltBin, rootDir, cfgPath, logPath, ka, db)","typeGuard":null,"tryCatchPattern":"srv, err := server.NewDoltServer(doltBin, rootDir, cfgPath, logPath, ka, db)\nif err != nil && strings.Contains(err.Error(), \"rootDir is required\") {\n    return fmt.Errorf(\"could not determine workspace root: %w\", err)\n}","preventionTips":["Always resolve the workspace root before constructing server objects","Check workspace initialization state at CLI entry","Never pass empty-string placeholders for required paths"],"tags":["go","config","validation"],"backgroundTag":"missing-config-value","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}