wtfutil/wtf · error
cannot expand user-specific home dir
Error message
cannot expand user-specific home dir
What it means
expandHomeDir expands a leading '~' in a config path to the user's home directory. It only supports the forms '~' and '~/...' (or '~\...'); any other character after the tilde (e.g. '~otheruser/docs') is unsupported and produces this error, because resolving another user's home is not attempted.
Source
Thrown at cfg/config_files.go:176
os.Exit(1)
}
}
}
// Expand expands the path to include the home directory if the path
// is prefixed with `~`. If it isn't prefixed with `~`, the path is
// returned as-is.
func expandHomeDir(path string) (string, error) {
if path == "" {
return path, nil
}
if path[0] != '~' {
return path, nil
}
if len(path) > 1 && path[1] != '/' && path[1] != '\\' {
return "", errors.New("cannot expand user-specific home dir")
}
dir, err := home()
if err != nil {
return "", err
}
return filepath.Join(dir, path[1:]), nil
}
// Dir returns the home directory for the executing user.
// An error is returned if a home directory cannot be detected.
func home() (string, error) {
currentUser, err := user.Current()
if err != nil {
return "", err
}
if currentUser.HomeDir == "" {View on GitHub (pinned to bb838c1ccb)
Solutions
- Use '~' or '~/...' form only; expand other users' homes yourself before calling
- Pre-resolve the path with os.UserHomeDir() or os.ExpandEnv and pass an absolute path
- Check for stray characters right after '~' in the path string (typo check)
Example fix
// before
home, err := cfg.LoadWtfConfigFile("~alice/.config/wtf/config.yml")
// after
aliceHome, _ := user.Lookup("alice")
home, err := cfg.LoadWtfConfigFile(filepath.Join(aliceHome.HomeDir, ".config/wtf/config.yml")) Defensive patterns
Strategy: validation
Validate before calling
if strings.HasPrefix(path, "~") && len(path) > 1 && path[1] != '/' && path[1] != '\\' {
return errors.New("only ~/ paths are supported, not ~user")
} Type guard
func isExpandableTildePath(p string) bool {
return p == "~" || (len(p) > 1 && p[0] == '~' && (p[1] == '/' || p[1] == '\\'))
} Try / catch
path, err := cfg.ExpandHomeDir(rawPath)
if err != nil {
log.Fatalf("bad config path %q: %v", rawPath, err)
} Prevention
- Never use ~user syntax in wtfutil config paths
- Expand other users' homes with user.Lookup before passing paths
- Prefer absolute paths in service/systemd configurations
- Sanity-check paths copied from shell dotfile snippets
When it happens
Trigger: Passing a config path like '~bob/wtf/config.yml' or '~root/...' to WtfConfigDir, LoadWtfConfigFile, chmodConfigFile, or migrateOldConfig; a WTF_CONFIG-style env var or -c flag containing '~username' syntax.
Common situations: Users copying Unix shell tilde-expansion conventions (which support ~user) into wtfutil config paths or launchd/systemd service definitions; typos like '~ name' or '~/~/x'.
Related errors
- cannot find user-specific home dir
- panic(err)
- panic(err)
- invalid app index selected
- cannot store secrets: wtf.secretStore is not configured
AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03).
Data as JSON: /api/errors/47864fd5529bed9a.
Report an issue: GitHub.