{"record":{"id":"aa79f5b2855ab92c","repo":"coreybutler/nvm-windows","slug":"failed-to-get-source-file-info-w","errorCode":null,"errorMessage":"failed to get source file info: %w","messagePattern":"failed to get source file info: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/utility/rename.go","lineNumber":76,"sourceCode":"\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create destination directory: %w\", err)\n\t}\n\n\tdestFile, err := os.Create(new)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create destination file: %w\", err)\n\t}\n\tdefer destFile.Close()\n\n\t_, err = io.Copy(destFile, srcFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to copy data: %w\", err)\n\t}\n\n\t// Copy file permissions\n\tinfo, err := srcFile.Stat()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get source file info: %w\", err)\n\t}\n\terr = os.Chmod(new, info.Mode())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to set permissions on destination file: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// copyDir recursively copies a directory from old path to new path.\nfunc copyDir(old, new string) error {\n\tentries, err := os.ReadDir(old)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read source directory: %w\", err)\n\t}\n\n\t// Ensure destination directory exists\n\terr = os.MkdirAll(new, os.ModePerm)","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/coreybutler/nvm-windows/blob/5b18223ca19ff50d707f35410dbc6bd440a9f74d/src/utility/rename.go#L58-L94","documentation":"In copyFile(), after data is copied, srcFile.Stat() fetches the source's FileInfo so its permission mode can be cloned to the destination. This error means that stat call failed — rare, because the same handle was just read successfully. It usually indicates the file was deleted/renamed underneath the open handle or a filesystem-level fault.","triggerScenarios":"copyFile where, between opening/copying and stat-ing, the source is deleted by a concurrent process, or the underlying volume suffers an I/O error.","commonSituations":"Two nvm commands racing on the same version directory; antivirus quarantining the source file mid-operation; flaky removable media.","solutions":["Retry the operation with no concurrent nvm commands running (close other terminals using nvm).","Add antivirus exclusions for the NVM_HOME directory to prevent mid-copy quarantine.","If on removable media, verify the media's integrity and re-copy.","As a code-level fix, fall back to the FileInfo from the earlier os.Stat or skip Chmod when this stat fails (permissions are non-critical on Windows)."],"exampleFix":"// before\ninfo, err := srcFile.Stat()\nif err != nil {\n    return fmt.Errorf(\"failed to get source file info: %w\", err)\n}\n\n// after: reuse the stat info Rename() already obtained, or tolerate failure\ninfo, err := srcFile.Stat()\nif err != nil {\n    // Non-fatal on Windows: destination already holds the data.\n    return nil\n}","handlingStrategy":"fallback","validationCode":"if _, err := os.Stat(old); err != nil { return err } // perform once, reuse FileInfo","typeGuard":null,"tryCatchPattern":"if err := copyAcrossDrives(old, new); err != nil && strings.Contains(err.Error(), \"source file info\") {\n    // data already copied; permission clone failed — accept the copy\n    err = nil\n}","preventionTips":["Avoid concurrent deletions of the source tree during copy.","Reuse an earlier Stat result instead of re-statting through the open handle.","Treat permission-clone failures as non-fatal on Windows."],"tags":["filesystem","stat","copy","race-condition","windows"],"backgroundTag":null,"analyzedSha":"5b18223ca19ff50d707f35410dbc6bd440a9f74d","analyzedAt":"2026-08-15T10:06:51.428Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}