hasura/graphql-engine · error

failed to create a symlink from %q to %q: %w

Error message

failed to create a symlink from %q to %q: %w

What it means

This error is thrown by the Go CLI plugin installer when it fails to create a symbolic link from the downloaded plugin binary into the plugin bin directory. The underlying OS error (permission denied, existing file, read-only filesystem, etc.) is wrapped with %w so the root cause is visible. It originates from createOrUpdateLink during installPlugin.

Source

Thrown at cli/plugins/util.go:220

			// If cloning the symlink fails on Windows because the user
			// does not have the required privileges, ignore the error and
			// fall back to copying the file contents.
			//
			// ERROR_PRIVILEGE_NOT_HELD is 1314 (0x522):
			// https://msdn.microsoft.com/en-us/library/windows/desktop/ms681385(v=vs.85).aspx
			var lerr *os.LinkError
			if stderrors.As(err, &lerr); !stderrors.Is(lerr.Err, syscall.Errno(1314)) {
				return errors.E(op, err)
			}

			err := copyFile(binary, dst, 0o755)
			if err != nil {
				return errors.E(op, err)
			}
		} else {
			return errors.E(
				op,
				fmt.Errorf("failed to create a symlink from %q to %q: %w", binary, dst, err),
			)
		}
	}

	return nil
}

// removeLink removes a symlink reference if exists.
func removeLink(path string) error {
	var op errors.Op = "plugins.removeLink"

	fi, err := os.Lstat(path)
	if stderrors.Is(err, fs.ErrNotExist) {
		return nil
	} else if err != nil {
		return errors.E(op, fmt.Errorf("failed to read the symlink in %q: %w", path, err))
	}

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Remove the stale destination file (e.g. rm ~/.hasura/plugins/bin/plugin.name) and retry the install.
  2. On Windows, enable Developer Mode or run the terminal as Administrator so os.Symlink is permitted.
  3. Verify the plugin bin directory exists and is writable: mkdir -p ~/.hasura/plugins/bin && check permissions.
  4. Re-run the install with --version to force a clean install path.

Example fix

// before
rm ~/.hasura/plugins/bin/hasura-cli-plugin  # fails silently?
hasura plugin install myplugin

// after
# ensure no regular file blocks the symlink
rm -f ~/.hasura/plugins/bin/myplugin*
hasura plugin install myplugin
Defensive patterns

Strategy: validation

Validate before calling

// before install: ensure the destination is absent or a symlink
binDir := filepath.Join(home, ".hasura", "plugins", "bin")
dst := filepath.Join(binDir, pluginName)
if fi, err := os.Lstat(dst); err == nil && fi.Mode()&os.ModeSymlink == 0 {
    os.Remove(dst) // clear stale regular file
}
os.MkdirAll(binDir, 0o755)

Try / catch

// Go: inspect the wrapped error chain
err := installPlugin(...)
if err != nil {
    var linkErr *os.LinkError
    if errors.As(err, &linkErr) { /* symlink privilege/existence issue */ }
}

Prevention

When it happens

Trigger: Calling the plugin install flow when the symlink creation via os.Symlink fails: the destination path already exists as a non-link file, the bin directory is not writable, or on Windows the process lacks the SeCreateSymbolicLinkPrivilege privilege.

Common situations: Running `hasura plugin install` without admin rights on Windows (no symlink privilege), a leftover regular file at the destination from a previous manual install, or a read-only or non-existent plugins bin directory (~/.hasura/plugins/bin).

Related errors


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