wtfutil/wtf · critical
panic(err)
Error message
panic(err)
What it means
migrateOldConfig moves an old config directory to the new location with Copy and unconditionally panics if the copy fails. This is an intentional fail-fast during app startup (Initialize path): the developers decided that a half-migrated config is unrecoverable, so a panic with the raw error is raised instead of returning an error.
Source
Thrown at cfg/config_files.go:220
// to the new, XDG-compatible location
func migrateOldConfig() {
srcDir, _ := expandHomeDir(WtfConfigDirV1)
destDir, _ := WtfConfigDir()
// If the old config directory doesn't exist, do not move
if _, err := os.Stat(srcDir); os.IsNotExist(err) {
return
}
// If the new config directory already exists, do not move
if _, err := os.Stat(destDir); err == nil {
return
}
// Time to move
err := Copy(srcDir, destDir)
if err != nil {
panic(err)
}
// Delete the old directory if the new one exists
if _, err := os.Stat(destDir); err == nil {
err := os.RemoveAll(srcDir)
if err != nil {
fmt.Println(err)
}
}
}
View on GitHub (pinned to bb838c1ccb)
Solutions
- Read the wrapped panic message to identify the OS-level cause (permission denied, no space, etc.) and fix that filesystem condition
- Manually copy the old config directory to the new location yourself, then restart so migration is skipped
- Check write permissions on the destination config directory for the user running the app
- Ensure sufficient disk space and that destDir is not a regular file
Example fix
// before $ whoami # wrong user, no write access to ~/.config # after sudo chown -R $(whoami) ~/.config/myapp && restart app
Defensive patterns
Strategy: fallback
Validate before calling
// check migration preconditions before startup
if _, err := os.Stat(destDir); err == nil {
// already migrated; skip
}
if err := unix.Access(filepath.Dir(destDir), unix.W_OK); err != nil {
log.Fatalf("config dir not writable: %v", err)
} Try / catch
// recover at startup so a failed migration doesn't kill the process
func safeInit() (ok bool) {
defer func() {
if r := recover(); r != nil {
log.Printf("config migration failed: %v", r)
ok = false
}
}()
Initialize(cfgPath)
return true
} Prevention
- Run the app as a user with write access to the config directory
- Ensure adequate disk space before upgrades
- Perform the directory copy manually if the destination already exists to skip migration
When it happens
Trigger: Initialize detects an old config directory and calls Copy(srcDir, destDir); the copy fails due to permission errors (read-only destination), disk full, srcDir unreadable, or destDir existing as a file.
Common situations: Upgrading the app under a service account that lacks write permission to ~/.config; running in a container with a read-only filesystem or small disk; stale lock/permission issues after switching users.
Related errors
- panic(err)
- cannot expand user-specific home dir
- cannot find user-specific home dir
- panic(err)
- panic(err)
AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03).
Data as JSON: /api/errors/649be5902327fbe2.
Report an issue: GitHub.