gastownhall/beads · error
invalid workspace path: %w
Error message
invalid workspace path: %w
What it means
safeWorkspacePath in cmd/bd/doctor/fix/common.go:103 wraps any failure of filepath.Abs(root) with this error. filepath.Abs essentially only fails when os.Getwd() fails and the root is relative, meaning the process has no readable working directory (e.g. deleted cwd). It indicates the workspace root itself could not be resolved to an absolute path, before any traversal checks run.
Source
Thrown at cmd/bd/doctor/fix/common.go:106
}
return dirs.resolved, nil
}
func localWorkspaceBeadsDir(path string) (string, error) {
absPath, err := filepath.Abs(path)
if err != nil {
return "", fmt.Errorf("invalid path: %w", err)
}
return filepath.Join(absPath, ".beads"), nil
}
// safeWorkspacePath resolves relPath within the workspace root and ensures it
// cannot escape the workspace via path traversal.
func safeWorkspacePath(root, relPath string) (string, error) {
absRoot, err := filepath.Abs(root)
if err != nil {
return "", fmt.Errorf("invalid workspace path: %w", err)
}
cleanRel := filepath.Clean(relPath)
if filepath.IsAbs(cleanRel) {
return "", fmt.Errorf("expected relative path, got absolute: %s", relPath)
}
joined := filepath.Join(absRoot, cleanRel)
rel, err := filepath.Rel(absRoot, joined)
if err != nil {
return "", fmt.Errorf("failed to resolve path: %w", err)
}
if rel == ".." || strings.HasPrefix(rel, ".."+string(os.PathSeparator)) {
return "", fmt.Errorf("path escapes workspace: %s", relPath)
}
return joined, nilView on GitHub (pinned to 71377f2769)
Solutions
- cd to an existing directory (or restart the shell) so os.Getwd() succeeds, then rerun the fix
- Pass an absolute workspace root (e.g. /home/me/project) instead of a relative one so filepath.Abs does not need os.Getwd()
- Verify the process's cwd exists: run `pwd` or check /proc/<pid>/cwd from another shell
- Check filesystem/permission problems that make stat on the cwd fail
Example fix
// before
fix.Do(".")
// after
fix.Do("/home/user/project") // absolute root avoids os.Getwd() dependency Defensive patterns
Strategy: validation
Validate before calling
root := "/abs/workspace"
if !filepath.IsAbs(root) {
if _, err := os.Getwd(); err != nil {
return fmt.Errorf("cwd unavailable: %w", err)
}
} Type guard
func hasResolvableRoot(root string) bool {
_, err := filepath.Abs(root)
return err == nil
} Try / catch
p, err := safeWorkspacePath(root, rel)
if err != nil {
if strings.HasPrefix(err.Error(), "invalid workspace path") {
// recover: use absolute root or fail fast
}
return err
} Prevention
- Always pass absolute workspace roots to path helpers
- Check os.Getwd() health in long-lived daemons before filesystem operations
- Restart shells after deleting their working directory
When it happens
Trigger: Calling safeWorkspacePath with a relative root while the process's current working directory has been deleted or is unreadable, so os.Getwd() inside filepath.Abs returns an error.
Common situations: A bd doctor fix running from a terminal whose cwd was removed (deleted directory, stale shell after rebasing/cleaning), or a daemon/service whose working directory was removed while it processes a relative workspace path.
Related errors
- server: NewDoltServer: failed to determine absolute path of
- server: NewDoltServer: failed to determine absolute path of
- server: NewDoltServer: failed to determine absolute path of
- server: NewDoltServer: failed to determine absolute path of
- identity: resolve root path: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/f1561076723d75e3.
Report an issue: GitHub.