{"record":{"id":"1f22febe64b2fada","repo":"hasura/graphql-engine","slug":"could-not-rename-copy-directory-q-to-q-w","errorCode":null,"errorMessage":"could not rename/copy directory %q to %q: %w","messagePattern":"could not rename/copy directory %q to %q: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/plugins/move.go","lineNumber":239,"sourceCode":"\n\ttmp, err := os.MkdirTemp(\"\", \"hasura-temp-move\")\n\tif err != nil {\n\t\treturn errors.E(op, fmt.Errorf(\"failed to find a temporary director: %w\", err))\n\t}\n\tdefer os.RemoveAll(tmp)\n\n\tif err = moveAllFiles(srcDir, tmp, fos); err != nil {\n\t\treturn errors.E(op, fmt.Errorf(\"failed to move files: %w\", err))\n\t}\n\n\tif err = renameOrCopy(tmp, installDir); err != nil {\n\t\tdefer func() {\n\t\t\tos.Remove(installDir)\n\t\t}()\n\n\t\treturn errors.E(\n\t\t\top,\n\t\t\tfmt.Errorf(\"could not rename/copy directory %q to %q: %w\", tmp, installDir, err),\n\t\t)\n\t}\n\n\treturn nil\n}\n\n// renameOrCopy will try to rename a dir or file. If rename is not supported, a manual copy will be performed.\n// Existing files at \"to\" will be deleted.\nfunc renameOrCopy(from, to string) error {\n\tvar op errors.Op = \"plugins.renameOrCopy\"\n\n\tfi, err := os.Stat(to)\n\tif err != nil && !stderrors.Is(err, fs.ErrNotExist) {\n\t\treturn errors.E(op, fmt.Errorf(\"error checking move target dir %q: %w\", to, err))\n\t}\n\n\tif fi != nil && fi.IsDir() {\n\t\terr := os.RemoveAll(to)","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/cli/plugins/move.go#L221-L257","documentation":"The final atomic-ish step of moveToInstallDir — renameOrCopy(tmp, installDir) moving the staged temp directory into the plugin's install directory — failed. The wrapped error comes from renameOrCopy: target stat/cleanup problems, os.Rename failure, or a failed cross-device copyTree fallback.","triggerScenarios":"Staging succeeded but the tmp→installDir rename failed: installDir exists and cannot be removed (permissions), a cross-device move (/tmp vs home) where copyTree also hit an error, or ENOSPC during the copy.","commonSituations":"/tmp on tmpfs while the plugins dir is on disk, and the copy runs out of space; leftover root-owned install dir from a previous sudo install; Windows file locking on the target.","solutions":["Check the wrapped error for the OS cause (permission, ENOSPC, EXDEV fallback failure)","Remove/clean the existing install dir for the plugin and any stale artifacts, then retry","Free disk space or set TMPDIR to a filesystem with room (ideally same device as the install dir)","Fix ownership of the plugins install tree so the current user can replace it"],"exampleFix":"# before: tmpfs /tmp too small for copy fallback\n# after\nTMPDIR=$HOME/tmp hasura plugins install my-plugin","handlingStrategy":"fallback","validationCode":"if fi, err := os.Stat(installDir); err == nil && fi.IsDir() {\n    if err := os.RemoveAll(installDir); err != nil { return fmt.Errorf(\"cannot clear old install: %w\", err) }\n}","typeGuard":null,"tryCatchPattern":"if err := installPlugin(p); err != nil && strings.Contains(err.Error(), \"could not rename/copy directory\") {\n    // clear installDir, ensure same-device TMPDIR with space, retry\n}","preventionTips":["Set TMPDIR to the same filesystem as the plugins dir to avoid EXDEV copies","Clean old install dirs before upgrade","Ensure the current user owns the install tree"],"tags":["go","filesystem","rename","cross-device"],"backgroundTag":"file-rename-failed","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}