{"record":{"id":"207313f9ac32ae9a","repo":"gastownhall/beads","slug":"s-w-207313","errorCode":null,"errorMessage":"%s: %w","messagePattern":"%s: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/user_config_path.go","lineNumber":51,"sourceCode":"\tif home, err := cleanAbsoluteUserDirectory(\"user home directory\", homeDir, homeErr); err != nil {\n\t\tcandidates.homeErr = err\n\t} else {\n\t\tcandidates.legacy = filepath.Clean(filepath.Join(home, \".beads\", \"config.yaml\"))\n\t\tcandidates.documented = filepath.Clean(filepath.Join(home, \".config\", \"bd\", \"config.yaml\"))\n\t}\n\n\tif nativeDir, err := cleanAbsoluteUserDirectory(\"native user config directory\", nativeConfigDir, nativeErr); err != nil {\n\t\tcandidates.nativeErr = err\n\t} else {\n\t\tcandidates.native = filepath.Clean(filepath.Join(nativeDir, \"bd\", \"config.yaml\"))\n\t}\n\n\treturn candidates\n}\n\nfunc cleanAbsoluteUserDirectory(label, path string, resolutionErr error) (string, error) {\n\tif resolutionErr != nil {\n\t\treturn \"\", fmt.Errorf(\"%s: %w\", label, resolutionErr)\n\t}\n\tcleaned := filepath.Clean(path)\n\tif !filepath.IsAbs(cleaned) {\n\t\treturn \"\", fmt.Errorf(\"%s %q is not an absolute native path\", label, path)\n\t}\n\treturn cleaned, nil\n}\n\n// UserConfigYamlPath resolves the user-level config.yaml to a cleaned,\n// absolute path suitable for native filesystem APIs. It prefers the documented\n// <home>/.config/bd location when that file exists, then an existing native\n// os.UserConfigDir location. For a new file it keeps the documented location\n// as the creation target when possible, falling back to the native location\n// only when the home directory itself cannot be resolved safely.\nfunc UserConfigYamlPath() (string, error) {\n\treturn selectUserConfigYamlPath(currentUserConfigYamlCandidates())\n}\n","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/config/user_config_path.go#L33-L69","documentation":"cleanAbsoluteUserDirectory validates a candidate user-directory path during config path resolution. If the directory resolution step (e.g. os.UserHomeDir or os.UserConfigDir) returned an error, it is wrapped as \"<label>: <cause>\"; if the resolved path is not absolute after cleaning, a separate \"not an absolute native path\" error is produced.","triggerScenarios":"A resolution function passed in as resolutionErr fails (HOME unset, no home directory for the user, unsupported platform) or the resolved path is relative/non-native when resolving user config directory candidates.","commonSituations":"Running in a container or CI where $HOME is unset or points to a nonexistent dir; running as a system user without a home directory; Windows paths leaking into POSIX checks or vice versa in cross-compiled binaries.","solutions":["Ensure HOME (or USERPROFILE on Windows) is set to an absolute existing directory","Run as a user that has a valid home directory (check /etc/passwd entry)","Export HOME=/path/to/dir in containers/CI before running bd","Unwrap the error to see the underlying OS resolver failure"],"exampleFix":"// before\nbd doctor // fails: \"home directory: $HOME is not defined\"\n// after (Dockerfile/CI)\nENV HOME=/root\ndocker run -e HOME=/root ... bd doctor","handlingStrategy":"validation","validationCode":"home := os.Getenv(\"HOME\") // or USERPROFILE on Windows\nif home == \"\" {\n    return errors.New(\"HOME is not set; set it to an absolute directory\")\n}\nif fi, err := os.Stat(home); err != nil || !fi.IsDir() || !filepath.IsAbs(home) {\n    return fmt.Errorf(\"HOME=%q is not an absolute existing directory\", home)\n}","typeGuard":"func hasValidHome() bool {\n    h, err := os.UserHomeDir()\n    return err == nil && filepath.IsAbs(h)\n}","tryCatchPattern":"if err := resolveUserConfigPath(); err != nil {\n    var labeled *wrapErr\n    if errors.As(err, &labeled) {\n        log.Printf(\"resolution failed at %s: %v\", labeled.Label(), errors.Unwrap(err))\n    }\n    return err\n}","preventionTips":["Always export HOME (POSIX) / USERPROFILE (Windows) in containers and CI","Run bd as a user with a valid home directory entry","Verify platform-consistent (native) absolute paths when cross-compiling","Prefer os.UserHomeDir/os.UserConfigDir over manual env reads in your own code"],"tags":["environment","home-directory","path-resolution"],"backgroundTag":"home-directory-not-set","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}