gastownhall/beads · error

failed to create git config directory: %w

Error message

failed to create git config directory: %w

What it means

setupGlobalGitIgnore creates a new global gitignore in the standard git config location (~/.config/git/ignore) when no existing global ignore file is found. Before writing it, it ensures the config directory exists with os.MkdirAll(configDir, 0755). If that fails, the wrapped error is returned — bd could not prepare the user-level git config directory, so the global ignore could not be installed.

Source

Thrown at cmd/bd/init_stealth.go:406

		// No global gitignore file configured, check if standard location exists
		configDir := filepath.Join(homeDir, ".config", "git")
		standardIgnorePath := filepath.Join(configDir, "ignore")

		if _, err := os.Stat(standardIgnorePath); err == nil {
			// Standard global gitignore file exists, use it
			// No need to set git config - git automatically uses this standard location
			ignorePath = standardIgnorePath
			if verbose {
				fmt.Printf("Using existing global gitignore file: %s\n", ignorePath)
			}
		} else {
			// No global gitignore file exists, create one in standard location
			// No need to set git config - git automatically uses this standard location
			ignorePath = standardIgnorePath

			// Ensure config directory exists
			if err := os.MkdirAll(configDir, 0755); err != nil {
				return fmt.Errorf("failed to create git config directory: %w", err)
			}

			if verbose {
				fmt.Printf("Creating new global gitignore file: %s\n", ignorePath)
			}
		}
	}

	// Read existing ignore file if it exists
	var existingContent string
	// #nosec G304 - user config path
	if content, err := os.ReadFile(ignorePath); err == nil {
		existingContent = string(content)
	}

	// Use absolute paths for this specific project (fixes GitHub #538)
	// This allows other projects to use beads openly while this one stays stealth
	beadsPattern := projectPath + "/.beads/"

View on GitHub (pinned to 71377f2769)

Solutions

  1. Fix ownership of ~/.config: sudo chown -R $(whoami):$(whoami) ~/.config (a previous sudo run likely created it as root).
  2. Verify HOME is set and writable: echo $HOME; touch $HOME/.config/test-write.
  3. If a regular file blocks the path (e.g. ~/.config is a file), rename or remove it and retry.
  4. Free disk space / raise quota on the home volume if ENOSPC.
  5. Set XDG_CONFIG_HOME to a writable directory as a workaround, or create ~/.config/git manually: mkdir -p ~/.config/git.

Example fix

// before (~/.config owned by root after sudo use)
drwx------ 3 root root ~/.config

// after
$ sudo chown -R $(whoami):$(whoami) ~/.config
$ bd init  # setupGlobalGitIgnore creates ~/.config/git/ignore successfully
Defensive patterns

Strategy: validation

Validate before calling

configDir, err := os.UserConfigDir() // mirrors what setupGlobalGitIgnore derives
if err != nil {
	fmt.Printf("config dir unavailable (check HOME/XDG_CONFIG_HOME): %v\n", err)
} else if probe := filepath.Join(configDir, ".bd-write-probe"); os.WriteFile(probe, nil, 0644) != nil {
	fmt.Printf("cannot create files in %s; fix ownership/permissions first\n", configDir)
} else {
	os.Remove(probe)
}

Try / catch

err := setupGlobalGitIgnore(verbose)
var perr *fs.PathError
if errors.As(err, &perr) && errors.Is(perr.Err, syscall.EACCES) {
	fmt.Printf("cannot create %s; run: sudo chown -R $(whoami) $(dirname %s)\n", perr.Path, perr.Path)
}

Prevention

When it happens

Trigger: os.MkdirAll(configDir, 0755) fails: HOME is unset or points somewhere non-writable, ~/.config exists but is owned by another user, a file named like the target directory is in the path, or the home filesystem is read-only/full.

Common situations: Running bd under sudo (HOME=/root vs. the real user) or in Docker with HOME unset; ~/.config owned by root after a misconfigured sudo run (classic chown-needed situation); XDG_CONFIG_HOME pointing to an unwritable path; disk quota exhausted on home volume; corporate-managed machines with locked-down profiles.

Related errors


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