{"record":{"id":"4a9e00cee8f000c0","repo":"yorukot/superfile","slug":"failed-to-remove-source-after-copy-w","errorCode":null,"errorMessage":"failed to remove source after copy: %w","messagePattern":"failed to remove source after copy: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/internal/file_operations.go","lineNumber":71,"sourceCode":"\t}\n\n\t// If on the same partition, attempt to rename (which will use the same inode)\n\tif sameDev {\n\t\tif err = os.Rename(src, dst); err == nil {\n\t\t\treturn nil\n\t\t}\n\t\t// If rename fails, fall back to copy+delete\n\t}\n\n\t// If on different partitions or rename failed, fall back to copy+delete\n\terr = copyElement(src, dst)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to copy: %w\", err)\n\t}\n\n\terr = os.RemoveAll(src)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to remove source after copy: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// copyElement handles copying of both files and directories\nfunc copyElement(src, dst string) error {\n\tsrcInfo, err := os.Stat(src)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to stat source: %w\", err)\n\t}\n\n\tif srcInfo.IsDir() {\n\t\treturn copyDir(src, dst, srcInfo)\n\t}\n\treturn copyFile(src, dst, srcInfo)\n}\n","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/yorukot/superfile/blob/b72f550bc6e75913f48eb49fdd258e1a2df2fe88/src/internal/file_operations.go#L53-L89","documentation":"After copyElement succeeds, moveElement removes the original with os.RemoveAll(src); this error wraps a failure of that removal. At this point the data is already copied — the destination is safe — but the source could not be deleted, so the move is incomplete and a duplicate remains.","triggerScenarios":"moveElement's copy phase succeeded but os.RemoveAll(src) fails: a file inside the source tree became read-only/owned by another user, a file was locked (Windows), or a new file appeared with no delete permission.","commonSituations":"Windows antivirus or another process holding the source open; source directory containing files owned by root; source files with permission 444/555; source modified concurrently during the copy.","solutions":["Free/fix permissions on the source tree (chmod u+w, correct ownership) and delete it manually.","Close processes holding files in the source (on Windows, check locks).","Since the copy already succeeded, manually remove the leftover source with rm -rf after verifying the destination.","Retry the move after resolving the lock; or treat it as a copy and clean up yourself."],"exampleFix":"// before\nchmod 555 /data/src           // removal fails after copy\n// after\nchmod -R u+w /data/src && rm -rf /data/src","handlingStrategy":"fallback","validationCode":"// ensure every entry in src is deletable before the move\nerr := filepath.WalkDir(src, func(p string, d fs.DirEntry, err error) error {\n    if err != nil { return err }\n    if !d.IsDir() {\n        if info, _ := d.Info(); info != nil && info.Mode().Perm()&0200 == 0 {\n            return fmt.Errorf(\"read-only file blocks removal: %s\", p)\n        }\n    }\n    return nil\n})","typeGuard":"func sourceStillExists(src string) bool {\n    _, err := os.Stat(src)\n    return err == nil\n}","tryCatchPattern":"if err := moveElement(src, dst); err != nil {\n    if strings.Contains(err.Error(), \"failed to remove source after copy\") {\n        log.Warnf(\"Copy succeeded; leftover source at %s — clean up manually\", src)\n        // data is safe at dst\n        return nil\n    }\n    return err\n}","preventionTips":["Ensure source files are owner-writable before initiating a move.","On Windows, avoid moving trees with files open in other applications.","After a partial move, verify dst contents before deleting leftovers.","Run moves as a user with delete permission over the whole source tree."],"tags":["filesystem","move","permissions","cleanup"],"backgroundTag":"cannot-remove-source","analyzedSha":"b72f550bc6e75913f48eb49fdd258e1a2df2fe88","analyzedAt":"2026-09-01T04:38:08.254Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}