{"record":{"id":"852eeba6b300123a","repo":"coreybutler/nvm-windows","slug":"failed-to-stat-source-w","errorCode":null,"errorMessage":"failed to stat source: %w","messagePattern":"failed to stat source: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/utility/rename.go","lineNumber":21,"sourceCode":"import (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n)\n\nfunc Rename(old, new string) error {\n\told_drive := filepath.VolumeName(old)\n\tnew_drive := filepath.VolumeName(new)\n\n\tif old_drive == new_drive {\n\t\treturn os.Rename(old, new)\n\t}\n\n\t// Get file or directory info\n\tinfo, err := os.Stat(old)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to stat source: %w\", err)\n\t}\n\n\t// If old is a directory, copy recursively\n\tif info.IsDir() {\n\t\terr = copyDir(old, new)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to copy directory: %w\", err)\n\t\t}\n\t} else {\n\t\t// Otherwise, copy a single file\n\t\terr = copyFile(old, new)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to copy file: %w\", err)\n\t\t}\n\t}\n\n\t// Remove the original source\n\terr = os.RemoveAll(old)","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/coreybutler/nvm-windows/blob/5b18223ca19ff50d707f35410dbc6bd440a9f74d/src/utility/rename.go#L3-L39","documentation":"Rename() in src/utility/rename.go falls back to copy-then-delete when source and destination are on different volumes (os.Rename cannot cross drives). This error means os.Stat on the source path failed, so the function could not even determine whether it is copying a file or a directory. The wrapped error is a *PathError naming the exact cause (not exist, permission denied, etc.).","triggerScenarios":"Calling utility.Rename(old, new) where filepath.VolumeName(old) != filepath.VolumeName(new) (e.g. C: to D:) and 'old' does not exist, is a dangling symlink, or is unreadable by the current user.","commonSituations":"nvm-windows 'nvm install'/'nvm use' moving node versions across drives when the symlinked version directory was removed manually; source path mistyped or deleted by an earlier failed operation; permission or long-path (MAX_PATH) issues on Windows.","solutions":["Check the wrapped *PathError in the message — if it says 'The system cannot find the file specified', re-create or re-select the source version before renaming.","Verify the source path exists with dir/exist checks before invoking Rename in a cross-volume scenario.","Run from an elevated prompt if the message shows 'Access is denied'.","Enable Windows long-path support (registry LongPathsEnabled) if the source path exceeds 260 characters."],"exampleFix":"// before\ninfo, err := os.Stat(old)\nif err != nil {\n    return fmt.Errorf(\"failed to stat source: %w\", err)\n}\n\n// after: give a clearer message with the offending path\ninfo, err := os.Stat(old)\nif err != nil {\n    return fmt.Errorf(\"failed to stat source %q before cross-volume move: %w\", old, err)\n}","handlingStrategy":"validation","validationCode":"// Pre-flight check before cross-volume rename\nfunc RenameChecked(old, new string) error {\n    if _, err := os.Lstat(old); err != nil {\n        return fmt.Errorf(\"source missing before rename: %w\", err)\n    }\n    return utility.Rename(old, new)\n}","typeGuard":null,"tryCatchPattern":"if err := utility.Rename(old, new); err != nil {\n    if os.IsNotExist(errors.Unwrap(err)) {\n        // source vanished — re-select/reinstall the version\n    }\n    return err\n}","preventionTips":["Run only one nvm command at a time so version directories are not deleted concurrently.","Verify source paths exist before cross-drive moves.","Keep NVM_HOME/NVM_SYMLINK consistent to avoid dangling version directories."],"tags":["filesystem","rename","cross-volume","windows"],"backgroundTag":null,"analyzedSha":"5b18223ca19ff50d707f35410dbc6bd440a9f74d","analyzedAt":"2026-08-15T10:06:51.428Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}