coreybutler/nvm-windows · critical
panic(err)
Error message
panic(err)
What it means
writeToErrorLog() is nvm-windows' last-resort logger: it opens error.log next to the nvm executable. If os.OpenFile fails, it panics — crashing the whole command with a Go runtime panic instead of a clean error. It fires when the nvm installation directory is not writable: installed under Program Files without elevation, directory locked down by policy, or NVM_HOME on read-only media.
Source
Thrown at src/nvm.go:79
var env = &Environment{
settings: home,
root: "",
symlink: symlink,
arch: strings.ToLower(os.Getenv("PROCESSOR_ARCHITECTURE")),
node_mirror: "",
npm_mirror: "",
proxy: "none",
originalpath: "",
originalversion: "",
verifyssl: true,
}
func writeToErrorLog(i interface{}, abort ...bool) {
exe, _ := os.Executable()
file, err := os.OpenFile(filepath.Join(filepath.Dir(exe), "error.log"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, os.ModePerm)
if err != nil {
panic(err)
}
defer file.Close()
msg := fmt.Sprintf("%v\n", i)
if _, ferr := file.WriteString(msg); ferr != nil {
panic(ferr)
}
if len(abort) > 0 && abort[0] {
fmt.Println(msg)
os.Exit(1)
}
}
type Notification struct {
AppID string `json:"app_id"`
Title string `json:"title"`
Message string `json:"message"`View on GitHub (pinned to 5b18223ca1)
Solutions
- Run the nvm command from an elevated (Administrator) prompt so error.log can be created.
- Install/relocate nvm to a user-writable directory (e.g. %APPDATA%\nvm or C:\nvm) and update NVM_HOME/NVM_SYMLINK and PATH.
- Verify the directory holding nvm.exe is writable: try creating a file there manually.
- As a code fix, replace panic with a graceful fallback (stderr + os.Exit(1)) so logging failure never crashes harder than the original error.
Example fix
// before
file, err := os.OpenFile(filepath.Join(filepath.Dir(exe), "error.log"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, os.ModePerm)
if err != nil {
panic(err)
}
// after: degrade gracefully — never crash the tool because logging failed
file, err := os.OpenFile(filepath.Join(filepath.Dir(exe), "error.log"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
if err != nil {
fmt.Fprintf(os.Stderr, "nvm: %v (additionally, could not write error.log: %v)\n", i, err)
if len(abort) > 0 && abort[0] {
os.Exit(1)
}
return
} Defensive patterns
Strategy: fallback
Validate before calling
// Before running nvm, verify its directory is writable
exe, _ := os.Executable()
probe := filepath.Join(filepath.Dir(exe), ".write-probe")
if f, err := os.Create(probe); err != nil {
return errors.New("nvm directory not writable — run elevated or relocate nvm")
} else { f.Close(); os.Remove(probe) } Try / catch
// Wrap nvm invocations and treat a Go panic in writeToErrorLog as a permissions problem
out, err := cmd.CombinedOutput()
if err != nil && strings.Contains(string(out), "panic: ") && strings.Contains(string(out), "error.log") {
return errors.New("nvm cannot write error.log — run from an elevated prompt")
} Prevention
- Install nvm in a user-writable directory (e.g. C:\nvm or %APPDATA%\nvm), not Program Files.
- Run nvm elevated when its home directory is protected.
- Ensure NVM_HOME points to a writable, mounted drive.
When it happens
Trigger: Any code path that logs via writeToErrorLog while the folder containing nvm.exe denies write access — most commonly running nvm non-elevated after installing to C:\Program Files\nodejs or similar protected locations.
Common situations: Corporate machines with locked-down Program Files; nvm.exe run from a read-only network share; NVM_HOME on a full or write-protected drive; antivirus blocking creation of error.log.
Related errors
- panic(ferr)
- failed to elevate permissions to create symlink
- failed to set file permissions: %v
- failed to create destination directory %s: %v
- Error rolling back node v%s installation: %v.
AI-assisted analysis of coreybutler/nvm-windows@5b18223ca1 (2026-08-15).
Data as JSON: /api/errors/52d1d5720f1ac52e.
Report an issue: GitHub.