coreybutler/nvm-windows · warning
failed to get source file info: %v
Error message
failed to get source file info: %v
What it means
After copying bytes, copyFile stats the source file to mirror its permissions. This error means os.Stat(src) failed at that point — the source vanished or became inaccessible between the copy (which succeeded through its open handle) and the stat call. It is a TOCTOU-style race, usually triggered by antivirus quarantine or a concurrent cleanup of the temp tree.
Source
Thrown at src/upgrade/upgrade.go:944
defer sourceFile.Close()
// Create the destination file
destinationFile, err := os.Create(dst)
if err != nil {
return fmt.Errorf("failed to create destination file: %v", err)
}
defer destinationFile.Close()
// Copy contents from the source file to the destination file
_, err = io.Copy(destinationFile, sourceFile)
if err != nil {
return fmt.Errorf("failed to copy file: %v", err)
}
// Optionally, copy file permissions (this can be skipped if not needed)
sourceInfo, err := os.Stat(src)
if err != nil {
return fmt.Errorf("failed to get source file info: %v", err)
}
err = os.Chmod(dst, sourceInfo.Mode())
if err != nil {
return fmt.Errorf("failed to set file permissions: %v", err)
}
return nil
}
// copyDirContents copies all the contents (files and subdirectories) of a source directory to a destination directory.
func copyDirContents(srcDir, dstDir string) error {
// Ensure destination directory exists
err := os.MkdirAll(dstDir, 0755)
if err != nil {
return fmt.Errorf("failed to create destination directory %s: %v", dstDir, err)
}
View on GitHub (pinned to 5b18223ca1)
Solutions
- Add antivirus exclusions for the nvm temp pattern and NVM_HOME, then retry.
- Close temp-cleanup tools during the upgrade.
- Stat once before the copy and reuse that FileInfo instead of re-statting (code-level fix).
- Retry — if the file survived this time the stat succeeds.
Example fix
// before
_, err = io.Copy(destinationFile, sourceFile)
...
sourceInfo, err := os.Stat(src)
// after: capture the stat for free from the open handle
sourceInfo, err := sourceFile.Stat()
if err != nil {
return fmt.Errorf("failed to get source file info: %v", err)
} Defensive patterns
Strategy: fallback
Try / catch
Treat as non-fatal: the copy already succeeded, so log the stat failure, keep default permissions on the destination, and continue the upgrade.
Prevention
- Use the already-open file handle (sourceFile.Stat()) instead of re-statting by name.
- Exclude nvm temp dirs from AV to avoid the delete-after-copy race.
When it happens
Trigger: AV deleting the source file microseconds after io.Copy finishes; another process pruning the nvm-upgrade-* temp dir mid-upgrade; source on removable/network media disconnected mid-operation.
Common situations: Aggressive real-time scanners treating just-downloaded exes as threats; temp-cleaner utilities; very slow disks making the race window wide.
Related errors
- Error rolling back node v%s installation: %v.
- unscheduling error: %v
- Error computing checksum: %v
- failed to copy file: %v
- error accessing %s: %v
AI-assisted analysis of coreybutler/nvm-windows@5b18223ca1 (2026-08-15).
Data as JSON: /api/errors/92d60c63e65c45f7.
Report an issue: GitHub.