hasura/graphql-engine · error

error cleaning up dir %q: %w

Error message

error cleaning up dir %q: %w

What it means

renameOrCopy found that the destination already exists as a directory and os.RemoveAll(to) failed while trying to clear it before the rename. The old install directory could not be deleted, so it cannot be replaced.

Source

Thrown at cli/plugins/move.go:259

	}

	return nil
}

// renameOrCopy will try to rename a dir or file. If rename is not supported, a manual copy will be performed.
// Existing files at "to" will be deleted.
func renameOrCopy(from, to string) error {
	var op errors.Op = "plugins.renameOrCopy"

	fi, err := os.Stat(to)
	if err != nil && !stderrors.Is(err, fs.ErrNotExist) {
		return errors.E(op, fmt.Errorf("error checking move target dir %q: %w", to, err))
	}

	if fi != nil && fi.IsDir() {
		err := os.RemoveAll(to)
		if err != nil {
			return errors.E(op, fmt.Errorf("error cleaning up dir %q: %w", to, err))
		}
	}

	err = os.Rename(from, to)
	// Fallback for invalid cross-device link (errno:18).
	if isCrossDeviceRenameErr(err) {
		copyErr := copyTree(from, to)
		if copyErr != nil {
			return errors.E(
				op,
				fmt.Errorf("failed to copy directory tree as a fallback: %w", copyErr),
			)
		}

		return nil
	}

	if err != nil {

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Inspect ownership of the destination dir quoted in the error; chown -R to the current user or remove with appropriate privileges
  2. Close processes/AV locks on Windows; retry after they release
  3. Remount or relocate the plugins dir to a writable filesystem
  4. Manually remove the stale install dir and re-run the install

Example fix

# before
sudo rm -rf ~/.local/share/hasura/plugins  # then still root? no:
# after
sudo chown -R $(id -u) ~/.local/share/hasura/plugins
hasura plugins install my-plugin
Defensive patterns

Strategy: try-catch

Validate before calling

if fi, err := os.Stat(to); err == nil && fi.IsDir() {
    if err := os.RemoveAll(to); err != nil { return fmt.Errorf("pre-clean failed: %w", err) }
}

Try / catch

if err := moveToInstallDir(...); err != nil && strings.Contains(err.Error(), "cleaning up dir") {
    // chown -R the target dir to the user, remove manually, retry install
}

Prevention

When it happens

Trigger: The destination directory exists and RemoveAll fails: files inside are owned by another user/root, the filesystem is read-only, a file is locked (Windows), or an I/O error occurs mid-delete.

Common situations: Upgrading a plugin whose earlier install was done with sudo (root-owned files); Windows AV/indexer holding handles; read-only container volume for the plugins dir.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/fc8f9d9587f09b5a. Report an issue: GitHub.