{"record":{"id":"be08df6d92a15b93","repo":"gastownhall/beads","slug":"dolt-directory-is-required","errorCode":null,"errorMessage":"dolt directory is required","messagePattern":"dolt directory is required","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/doltserver/doltserver.go","lineNumber":1903,"sourceCode":"\tif out, err := exec.Command(\"dolt\", \"config\", \"--global\", \"--add\", \"user.email\", gitEmail).CombinedOutput(); err != nil {\n\t\treturn fmt.Errorf(\"setting dolt user.email: %w\\n%s\", err, out)\n\t}\n\n\treturn nil\n}\n\n// bdDoltMarker is written after a current bd process creates or acknowledges a\n// local Dolt repository. Its absence in an existing .dolt/ directory indicates\n// the database was created by a pre-0.56 bd version (which used embedded mode).\n// Those databases are incompatible with the current server-only architecture.\nconst bdDoltMarker = \".bd-dolt-ok\"\n\n// MarkDoltDirCompatible writes the canonical bd compatibility marker when\n// doltDir contains a local Dolt repository. It no-ops when there is no .dolt/\n// directory, which lets server and repair paths call it defensively.\nfunc MarkDoltDirCompatible(doltDir string) error {\n\tif doltDir == \"\" {\n\t\treturn errors.New(\"dolt directory is required\")\n\t}\n\tdotDolt := filepath.Join(doltDir, \".dolt\")\n\tif info, err := os.Stat(dotDolt); err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"checking dolt metadata directory %s: %w\", dotDolt, err)\n\t} else if !info.IsDir() {\n\t\treturn fmt.Errorf(\"dolt metadata path %s is not a directory\", dotDolt)\n\t}\n\tmarkerPath := filepath.Join(doltDir, bdDoltMarker)\n\tif _, err := os.Stat(markerPath); err == nil {\n\t\treturn nil\n\t} else if !os.IsNotExist(err) {\n\t\treturn fmt.Errorf(\"checking dolt compatibility marker %s: %w\", markerPath, err)\n\t}\n\tif err := os.WriteFile(markerPath, []byte(\"ok\\n\"), 0600); err != nil {\n\t\treturn fmt.Errorf(\"writing dolt compatibility marker %s: %w\", markerPath, err)","sourceCodeStart":1885,"sourceCodeEnd":1921,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/doltserver/doltserver.go#L1885-L1921","documentation":"MarkDoltDirCompatible writes the .bd-dolt-ok compatibility marker into a Dolt directory and requires a non-empty doltDir path. When called with an empty string it returns \"dolt directory is required\" immediately, because there is no directory to inspect or mark. The function intentionally no-ops (returns nil) when no .dolt/ directory exists, so the empty-path case is the only hard input validation failure.","triggerScenarios":"Calling doltserver.MarkDoltDirCompatible(\"\") — e.g. when the configured bd data directory variable was never populated (missing/unset BEADS_DIR or equivalent config resolution returned empty) before server startup or repair paths invoke the marker writer.","commonSituations":"A config/environment resolution bug yields an empty database dir; calling the repair/defensive marker path in a script or test before any directory is configured; refactoring code that used to pass a hardcoded path to now pass a variable that is empty on first run.","solutions":["Fix the caller to pass the resolved bd data directory (ensure config resolution / BEADS_DIR handling populates doltDir before calling)","Initialize the dolt directory first via ensureDoltInit / bd init so a valid path exists","Guard the call site: skip MarkDoltDirCompatible when the path is empty and surface a configuration error instead"],"exampleFix":"// before\nif err := doltserver.MarkDoltDirCompatible(cfgDir); err != nil { ... }\n// after\nif cfgDir == \"\" {\n    return fmt.Errorf(\"bd data directory not configured\")\n}\nif err := doltserver.MarkDoltDirCompatible(cfgDir); err != nil { ... }","handlingStrategy":"validation","validationCode":"if doltDir == \"\" {\n    return fmt.Errorf(\"bd data directory not configured (BEADS_DIR unset?)\")\n}\nif err := doltserver.MarkDoltDirCompatible(doltDir); err != nil {\n    return err\n}","typeGuard":null,"tryCatchPattern":"if err := doltserver.MarkDoltDirCompatible(doltDir); err != nil {\n    if strings.Contains(err.Error(), \"dolt directory is required\") { /* config bug: fix caller */ }\n    return fmt.Errorf(\"mark dolt dir compatible: %w\", err)\n}","preventionTips":["Resolve the bd data directory through config helpers once at startup and fail fast if empty","Never pass raw environment variables directly without an empty-check","Treat MarkDoltDirCompatible as post-init: only call after ensureDoltInit or bd init succeeded"],"tags":["go","configuration","dolt"],"backgroundTag":"missing-required-path","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}