gastownhall/beads · error

invalid path: %w

Error message

invalid path: %w

What it means

resolveWorkspaceBeadsDirs converts the given workspace path to an absolute path before locating .beads directories. If filepath.Abs fails (which requires the process working directory to be resolvable), the whole directory resolution fails with this wrapped error.

Source

Thrown at cmd/bd/doctor/fix/common.go:69

	bdPath, err := exec.LookPath("bd")
	if err != nil {
		return "", fmt.Errorf("bd binary not found in PATH: %w", err)
	}

	return bdPath, nil
}

// validateBeadsWorkspace ensures the path is a valid beads workspace before
// attempting any fix operations. This prevents path traversal attacks.
func validateBeadsWorkspace(path string) error {
	_, err := resolveWorkspaceBeadsDirs(path)
	return err
}

func resolveWorkspaceBeadsDirs(path string) (workspaceBeadsDirs, error) {
	absPath, err := filepath.Abs(path)
	if err != nil {
		return workspaceBeadsDirs{}, fmt.Errorf("invalid path: %w", err)
	}

	dirs := workspaceBeadsDirs{
		local:    filepath.Join(absPath, ".beads"),
		resolved: beads.ResolveBeadsDirForRepo(absPath),
	}

	if info, err := os.Stat(dirs.resolved); err != nil || !info.IsDir() {
		return workspaceBeadsDirs{}, fmt.Errorf("not a beads workspace: .beads directory not found for %s", absPath)
	}

	return dirs, nil
}

func resolvedWorkspaceBeadsDir(path string) (string, error) {
	dirs, err := resolveWorkspaceBeadsDirs(path)
	if err != nil {
		return "", err

View on GitHub (pinned to 71377f2769)

Solutions

  1. Pass an absolute path to the API to bypass cwd resolution entirely.
  2. cd to a valid directory (e.g. the workspace root) before running the command.
  3. Restart the shell/process if its cwd was deleted, then re-run.
  4. Check the wrapped os.Getwd-style error in %w to confirm the cwd problem.

Example fix

// before
validateBeadsWorkspace(".")           // fails if cwd deleted
// after
validateBeadsWorkspace("/path/to/repo") // absolute path, no cwd dependency
Defensive patterns

Strategy: validation

Validate before calling

abs, err := filepath.Abs(path)
if err != nil {
	// cwd unusable; switch to a valid directory or pass absolute path
	return err
}
if fi, err := os.Stat(abs); err != nil || !fi.IsDir() {
	return fmt.Errorf("workspace path missing: %s", abs)
}

Try / catch

if err := fix.Permissions(path); err != nil && strings.Contains(err.Error(), "invalid path") {
	// retry with an absolute path from a valid working directory
	return err
}

Prevention

When it happens

Trigger: filepath.Abs(path) returns an error in resolveWorkspaceBeadsDirs (cmd/bd/doctor/fix/common.go:69) — almost always because the current working directory was deleted or is unreadable when a relative path is passed to validateBeadsWorkspace, resolvedWorkspaceBeadsDir, or Permissions.

Common situations: Running a fix from a shell whose cwd was removed (e.g. after `rm -rf` of the directory in another terminal); containers that start in a deleted mount point; relative path passed while process cwd is invalid.

Related errors


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