{"record":{"id":"730c3e581d4cc8de","repo":"coreybutler/nvm-windows","slug":"failed-to-remove-source-w","errorCode":null,"errorMessage":"failed to remove source: %w","messagePattern":"failed to remove source: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/utility/rename.go","lineNumber":41,"sourceCode":"\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)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to remove source: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// copyFile copies a single file from source (old) to destination (new).\nfunc copyFile(old, new string) error {\n\tsrcFile, err := os.Open(old)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to open source file: %w\", err)\n\t}\n\tdefer srcFile.Close()\n\n\t// Ensure destination directory exists\n\tdestDir := filepath.Dir(new)\n\terr = os.MkdirAll(destDir, os.ModePerm)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create destination directory: %w\", err)","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/coreybutler/nvm-windows/blob/5b18223ca19ff50d707f35410dbc6bd440a9f74d/src/utility/rename.go#L23-L59","documentation":"In Rename()'s cross-volume fallback, once the source has been successfully copied to the destination, os.RemoveAll(old) deletes the original. This error means that cleanup deletion failed. Data is usually NOT lost — the copy exists at the destination — but the stale source remains and the operation is reported as failed.","triggerScenarios":"utility.Rename(old, new) across volumes where the copy succeeded but the source tree cannot be removed: a file inside is open (running node.exe/npm.cmd), a read-only attribute blocks deletion, or another process (antivirus, indexer) holds a handle.","commonSituations":"Moving a node version while a terminal still has its npm.cmd or node.exe running; Windows Search or Defender transiently holding handles; source files marked read-only after being restored from backup.","solutions":["Since the copy already succeeded, simply delete the leftover source directory manually once no processes use it: rmdir /s /q <old>.","Terminate node.exe/npm processes and re-run the original nvm command.","Clear read-only attributes: attrib -r <old>\\*.* /s /d, then delete.","Run elevated if removal is denied by ACLs."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := utility.Rename(old, new); err != nil {\n    if strings.Contains(err.Error(), \"failed to remove source\") {\n        // Copy already succeeded — treat as success and clean up later\n        go os.RemoveAll(old)\n        err = nil\n    }\n}","preventionTips":["Treat 'failed to remove source' as a benign cleanup failure — data is already copied.","Delete leftover source directories manually once processes release them.","Clear read-only attributes on the source tree before moving."],"tags":["filesystem","delete","cross-volume","windows","cleanup"],"backgroundTag":null,"analyzedSha":"5b18223ca19ff50d707f35410dbc6bd440a9f74d","analyzedAt":"2026-08-15T10:06:51.428Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}