coreybutler/nvm-windows · warning
failed to encode path: %w
Error message
failed to encode path: %w
What it means
setHidden marks the .update directory hidden by calling kernel32's SetFileAttributesW via syscall, and first converts the path to a UTF-16 pointer. This error means syscall.UTF16PtrFromString rejected the path — in Go that happens only when the string contains a NUL rune, which renders it unusable as a C wide string. A real path essentially never contains NUL, so this firing indicates a corrupted constructed path rather than a user-visible input problem.
Source
Thrown at src/upgrade/upgrade.go:1062
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(writer, file)
if err != nil {
return err
}
}
return nil
})
}
func setHidden(path string) error {
// Convert the path to a UTF-16 encoded string
lpFileName, err := syscall.UTF16PtrFromString(path)
if err != nil {
return fmt.Errorf("failed to encode path: %w", err)
}
// Call the Windows API function
ret, _, err := syscall.NewLazyDLL("kernel32.dll").
NewProc("SetFileAttributesW").
Call(
uintptr(unsafe.Pointer(lpFileName)),
uintptr(FILE_ATTRIBUTE_HIDDEN),
)
// Check the result
if ret == 0 {
return fmt.Errorf("failed to set hidden attribute: %w", err)
}
return nil
}
View on GitHub (pinned to 5b18223ca1)
Solutions
- Treat it as a signal of path corruption: log the exact path passed to setHidden and inspect where it was built.
- Sanitize NVM_HOME/currentPath: reject strings containing \x00 before use.
- Note the failure is cosmetic — the directory just stays visible; nothing else breaks.
Example fix
// before
lpFileName, err := syscall.UTF16PtrFromString(path)
if err != nil {
return fmt.Errorf("failed to encode path: %w", err)
}
// after: validate NUL-free explicitly and surface which path was bad
if strings.ContainsRune(path, 0) {
return fmt.Errorf("invalid path (contains NUL): %q", path)
}
lpFileName, err := syscall.UTF16PtrFromString(path)
if err != nil {
return fmt.Errorf("failed to encode path %q: %w", path, err)
} Defensive patterns
Strategy: type-guard
Validate before calling
if strings.ContainsRune(path, 0) {
return fmt.Errorf("refusing to hide path containing NUL: %q", path)
} Type guard
func isValidWin32Path(p string) bool {
return p != "" && !strings.ContainsRune(p, 0)
} Try / catch
Treat as best-effort: the hidden attribute is cosmetic, so on UTF16PtrFromString failure log and continue rather than failing the upgrade.
Prevention
- Validate NVM_HOME contains no control characters at install time.
- Never construct paths from unsanitized config strings.
- Treat NUL-in-path as corruption and investigate upstream path building.
When it happens
Trigger: filepath.Join(currentPath, ".update") somehow containing an embedded NUL (memory corruption or a malformed currentPath from os.Executable); on non-Windows builds where path handling produces unexpected runes; programmatically calling setHidden with attacker- or config-controlled strings containing \x00.
Common situations: Effectively never in normal operation; conceivable with exotic environments that mangle os.Executable output or with NUL bytes injected via misconfigured NVM_HOME.
Related errors
AI-assisted analysis of coreybutler/nvm-windows@5b18223ca1 (2026-08-15).
Data as JSON: /api/errors/60e3be38113c88d7.
Report an issue: GitHub.