{"record":{"id":"331673f46eb0598b","repo":"gastownhall/beads","slug":"failed-to-create-git-config-directory-w","errorCode":null,"errorMessage":"failed to create git config directory: %w","messagePattern":"failed to create git config directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/init_stealth.go","lineNumber":406,"sourceCode":"\t\t// No global gitignore file configured, check if standard location exists\n\t\tconfigDir := filepath.Join(homeDir, \".config\", \"git\")\n\t\tstandardIgnorePath := filepath.Join(configDir, \"ignore\")\n\n\t\tif _, err := os.Stat(standardIgnorePath); err == nil {\n\t\t\t// Standard global gitignore file exists, use it\n\t\t\t// No need to set git config - git automatically uses this standard location\n\t\t\tignorePath = standardIgnorePath\n\t\t\tif verbose {\n\t\t\t\tfmt.Printf(\"Using existing global gitignore file: %s\\n\", ignorePath)\n\t\t\t}\n\t\t} else {\n\t\t\t// No global gitignore file exists, create one in standard location\n\t\t\t// No need to set git config - git automatically uses this standard location\n\t\t\tignorePath = standardIgnorePath\n\n\t\t\t// Ensure config directory exists\n\t\t\tif err := os.MkdirAll(configDir, 0755); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to create git config directory: %w\", err)\n\t\t\t}\n\n\t\t\tif verbose {\n\t\t\t\tfmt.Printf(\"Creating new global gitignore file: %s\\n\", ignorePath)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Read existing ignore file if it exists\n\tvar existingContent string\n\t// #nosec G304 - user config path\n\tif content, err := os.ReadFile(ignorePath); err == nil {\n\t\texistingContent = string(content)\n\t}\n\n\t// Use absolute paths for this specific project (fixes GitHub #538)\n\t// This allows other projects to use beads openly while this one stays stealth\n\tbeadsPattern := projectPath + \"/.beads/\"","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/init_stealth.go#L388-L424","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix ownership of ~/.config: sudo chown -R $(whoami):$(whoami) ~/.config (a previous sudo run likely created it as root).","Verify HOME is set and writable: echo $HOME; touch $HOME/.config/test-write.","If a regular file blocks the path (e.g. ~/.config is a file), rename or remove it and retry.","Free disk space / raise quota on the home volume if ENOSPC.","Set XDG_CONFIG_HOME to a writable directory as a workaround, or create ~/.config/git manually: mkdir -p ~/.config/git."],"exampleFix":"// before (~/.config owned by root after sudo use)\ndrwx------ 3 root root ~/.config\n\n// after\n$ sudo chown -R $(whoami):$(whoami) ~/.config\n$ bd init  # setupGlobalGitIgnore creates ~/.config/git/ignore successfully","handlingStrategy":"validation","validationCode":"configDir, err := os.UserConfigDir() // mirrors what setupGlobalGitIgnore derives\nif err != nil {\n\tfmt.Printf(\"config dir unavailable (check HOME/XDG_CONFIG_HOME): %v\\n\", err)\n} else if probe := filepath.Join(configDir, \".bd-write-probe\"); os.WriteFile(probe, nil, 0644) != nil {\n\tfmt.Printf(\"cannot create files in %s; fix ownership/permissions first\\n\", configDir)\n} else {\n\tos.Remove(probe)\n}","typeGuard":null,"tryCatchPattern":"err := setupGlobalGitIgnore(verbose)\nvar perr *fs.PathError\nif errors.As(err, &perr) && errors.Is(perr.Err, syscall.EACCES) {\n\tfmt.Printf(\"cannot create %s; run: sudo chown -R $(whoami) $(dirname %s)\\n\", perr.Path, perr.Path)\n}","preventionTips":["Never run bd under sudo for user-level setup; if you did, chown ~/.config back to your user.","Ensure HOME (and XDG_CONFIG_HOME if set) point to writable directories, especially in containers/CI.","Keep ~/.config a directory, never a regular file.","Maintain free disk space on the home volume."],"tags":["git","global-config","mkdir","permissions","home-directory"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}