gastownhall/beads · error

unable to determine home directory: %w

Error message

unable to determine home directory: %w

What it means

GetClaudePluginVersion first resolves the user's home directory via os.UserHomeDir; if that fails (no HOME env on Unix, missing user profile on Windows), it wraps the OS error. Without a home directory it cannot locate ~/.claude/plugins/installed_plugins.json to read the beads plugin version.

Source

Thrown at cmd/bd/doctor/claude.go:538

			Status:  StatusWarning,
			Message: "beads plugin not installed",
			Fix:     "Install plugin: /plugin marketplace add steveyegge/beads && /plugin install beads (see docs/integrations/claude-code-plugin.md)",
		}
	}

	return DoctorCheck{
		Name:    "Claude Plugin",
		Status:  StatusOK,
		Message: fmt.Sprintf("version %s (update check skipped in non-interactive mode)", pluginVersion),
	}
}

// GetClaudePluginVersion returns the installed beads Claude plugin version.
func GetClaudePluginVersion() (version string, installed bool, err error) {
	// Get user home directory (cross-platform)
	homeDir, err := os.UserHomeDir()
	if err != nil {
		return "", false, fmt.Errorf("unable to determine home directory: %w", err)
	}

	// Path to installed_plugins.json
	pluginPath := filepath.Join(homeDir, ".claude", "plugins", "installed_plugins.json")

	// Read plugin file
	data, err := os.ReadFile(pluginPath) // #nosec G304 - path is controlled
	if err != nil {
		if os.IsNotExist(err) {
			return "", false, nil
		}
		return "", false, fmt.Errorf("unable to read plugin file: %w", err)
	}

	// First, determine the format version
	var versionCheck struct {
		Version int `json:"version"`
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Set HOME to your real home directory (export HOME=/home/<user>) before running bd
  2. Run bd as a normal user with an existing home directory instead of a system account
  3. In containers/CI, explicitly set HOME in the Dockerfile/pipeline (ENV HOME=/root)
  4. Verify the current user has a valid entry in /etc/passwd (or a Windows profile)

Example fix

# before (CI step)
- run: bd doctor
# after
- run: |
    export HOME=/root
    bd doctor
Defensive patterns

Strategy: fallback

Validate before calling

import "os"
func homeOr(dir string) string {
	if h, err := os.UserHomeDir(); err == nil { return h }
	return dir
}

Try / catch

_, installed, err := GetClaudePluginVersion()
if err != nil {
	log.Printf("plugin check skipped (no home dir): %v", err)
	return // treat as not-installed rather than failing doctor
}

Prevention

When it happens

Trigger: GetClaudePluginVersion (via CheckClaudePlugin during `bd doctor`) when os.UserHomeDir returns an error — typically $HOME unset/empty on Linux, or the user account lacking a resolvable profile — at cmd/bd/doctor/claude.go:538.

Common situations: Running bd in a minimal container or CI job with HOME unset; running under a service account (systemd, cron) without a home dir; Windows accounts without a user profile; sudo/su setups that clear HOME.

Related errors


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