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

  1. Treat it as a signal of path corruption: log the exact path passed to setHidden and inspect where it was built.
  2. Sanitize NVM_HOME/currentPath: reject strings containing \x00 before use.
  3. 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

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.