{"record":{"id":"73c79975eee2853f","repo":"gastownhall/beads","slug":"resolving-beads-dir-s-w","errorCode":null,"errorMessage":"resolving beads dir %s: %w","messagePattern":"resolving beads dir (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/doltserver/physical_root.go","lineNumber":250,"sourceCode":"//     (internal/storage/embeddeddolt), which is precisely where\n//     ResolveDoltDir is wrong (it reports beadsDir/dolt) and why this\n//     function does not reuse it wholesale.\n//  5. no metadata.json: after the shared-server rescue, mirror the open\n//     path's discovery fallback (internal/beads findDatabaseInBeadsDir):\n//     an embeddeddolt/ dir means embedded, else a dolt/ dir means a\n//     server-layout workspace, else default to the embedded root (which\n//     may not exist yet — gating a not-yet-existing root is fine, the gate\n//     file lives beside it and workspacegate only requires the PARENT to\n//     exist). The CLI's nil-config branch honors no other env rescue.\n//\n// Roots are returned absolute. Symlink canonicalization is deliberately NOT\n// performed here: workspacegate.ForPhysicalRoot canonicalizes the gate\n// file's parent itself (and refuses symlinked roots), and resolving here too\n// would double-handle and could disagree with the gate's own rules.\nfunc ResolvePhysicalRoots(beadsDir string) (PhysicalRoots, error) {\n\tabs, err := filepath.Abs(beadsDir)\n\tif err != nil {\n\t\treturn PhysicalRoots{}, fmt.Errorf(\"resolving beads dir %s: %w\", beadsDir, err)\n\t}\n\tabs = filepath.Clean(abs)\n\tpr := PhysicalRoots{BeadsDir: abs}\n\n\t// Side-effect-free config load: never trigger the legacy config.json\n\t// migration. Absent metadata.json is treated as cfg == nil.\n\tvar cfg *configfile.Config\n\tif _, statErr := os.Stat(configfile.ConfigPath(abs)); statErr == nil {\n\t\tloaded, loadErr := configfile.Load(abs)\n\t\tif loadErr != nil {\n\t\t\t// A present-but-broken metadata.json is authoritative: the open\n\t\t\t// path refuses to fall back, so gate planning refuses to guess.\n\t\t\treturn PhysicalRoots{}, fmt.Errorf(\"loading config for gate resolution: %w\", loadErr)\n\t\t}\n\t\tcfg = loaded\n\t}\n\n\taddRoot := func(root string) error {","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/doltserver/physical_root.go#L232-L268","documentation":"ResolvePhysicalRoots wraps filepath.Abs(beadsDir) failures as \"resolving beads dir %s: %w\". This function canonicalizes the beads directory into absolute physical roots used for gate-file planning; it throws when the OS cannot convert the given beads dir path to an absolute path — rare, and usually caused by extremely long paths (Windows MAX_PATH) or malformed input (empty string leading to getwd failure).","triggerScenarios":"ResolvePhysicalRoots is called (directly or by tests/startup) with a beadsDir for which filepath.Abs fails: empty string while the current working directory is unavailable (deleted cwd), or a path exceeding OS length limits.","commonSituations":"Running bd from a directory that was deleted or renamed while the shell sits in it (getwd fails); Windows paths beyond 260 chars without long-path support enabled; passing \"\" as beadsDir programmatically.","solutions":["cd to a valid existing directory before running bd, or pass an explicit --repo/path flag.","Shorten the path (move the workspace closer to the drive root) or enable Windows long paths (LongPathsEnabled registry / git config core.longpaths).","Ensure the beads dir argument passed to ResolvePhysicalRoots is non-empty and well-formed.","Re-create the deleted working directory or restart the shell so getwd returns a valid path."],"exampleFix":"// before\nResolvePhysicalRoots(\"\")            // cwd deleted -> getwd error\n// after\nabs, _ := filepath.EvalSymlinks(beadsDir)\nResolvePhysicalRoots(abs)           // e.g. \"/home/u/proj/.beads\"","handlingStrategy":"validation","validationCode":"if beadsDir == \"\" {\n    return fmt.Errorf(\"beadsDir must not be empty\")\n}\nif cwd, err := os.Getwd(); err != nil {\n    return fmt.Errorf(\"current directory unavailable (%v); cd to a valid dir\", err)\n} else if filepath.IsLocal(beadsDir) {\n    if _, err := os.Stat(filepath.Join(cwd, beadsDir)); err != nil {\n        return fmt.Errorf(\"beads dir %s not found\", beadsDir)\n    }\n}","typeGuard":"func resolvablePath(p string) bool {\n    if p == \"\" { return false }\n    if filepath.IsAbs(p) { _, err := os.Stat(p); return err == nil }\n    _, err := os.Getwd()\n    return err == nil\n}","tryCatchPattern":"roots, err := ResolvePhysicalRoots(beadsDir)\nif err != nil {\n    if strings.Contains(err.Error(), \"resolving beads dir\") {\n        return fmt.Errorf(\"bad --repo path %q or invalid cwd; pass an absolute path\", beadsDir)\n    }\n    return err\n}","preventionTips":["Pass absolute paths for the beads dir instead of relying on cwd","Restart the shell if the working directory was deleted/renamed","Enable Windows long paths for deep workspaces","Validate beadsDir existence before calling ResolvePhysicalRoots"],"tags":["filesystem","paths","configuration"],"backgroundTag":"path-resolution-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}