hasura/graphql-engine · error

error checking move target dir %q: %w

Error message

error checking move target dir %q: %w

What it means

renameOrCopy first stats the destination to decide whether it must be removed; os.Stat returned an error other than fs.ErrNotExist (which is expected and ignored). This means an unexpected filesystem-level failure inspecting the destination — permission on a parent directory, I/O error, or name-too-long.

Source

Thrown at cli/plugins/move.go:253

		}()

		return errors.E(
			op,
			fmt.Errorf("could not rename/copy directory %q to %q: %w", tmp, installDir, err),
		)
	}

	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),
			)

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Check the quoted destination path: verify each parent directory is searchable (x permission) by the current user
  2. Shorten / normalize the install path if ENAMETOOLONG
  3. Investigate dmesg / mount health for I/O errors or MAC denials on that filesystem
  4. Fix permissions, then retry the plugin install
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := os.Stat(to); err != nil && !errors.Is(err, fs.ErrNotExist) {
    return fmt.Errorf("destination not statable: %w", err)
}

Try / catch

var perr *fs.PathError
if errors.As(err, &perr) {
    switch {
    case os.IsPermission(perr): // fix search perms on parents
    case errors.Is(perr, fs.ErrNotExist): // treat as fresh install
    }
}

Prevention

When it happens

Trigger: os.Stat(to) failing with EACCES (search permission missing on a parent dir), EIO, ENAMETOOLONG, or similar, on the destination path of a file move or the final install dir rename.

Common situations: Install dir parents with restrictive modes; deeply nested paths exceeding NAME_MAX; failing disk/NFS mounts; SELinux/AppArmor denials on the plugins path.

Related errors


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