hasura/graphql-engine · error
failed to remove the symlink in %q: %w
Error message
failed to remove the symlink in %q: %w
What it means
After removeLink confirms the target is a symlink, os.Remove is called to delete it; this error wraps any failure of that deletion. It usually means the containing directory is not writable (deleting a file requires write permission on its directory, not on the file itself) or the file vanished between Lstat and Remove.
Source
Thrown at cli/plugins/util.go:244
}
// 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))
}
if fi.Mode()&os.ModeSymlink == 0 && !IsWindows() {
return errors.E(op, fmt.Errorf("file %q is not a symlink (mode=%s)", path, fi.Mode()))
}
if err := os.Remove(path); err != nil {
return errors.E(op, fmt.Errorf("failed to remove the symlink in %q: %w", path, err))
}
return nil
}
// PluginNameToBin creates the name of the symlink file for the plugin name.
// It converts dashes to underscores.
func PluginNameToBin(name string, isWindows bool) string {
name = strings.ReplaceAll(name, "-", "_")
name = "hasura-" + name
if isWindows {
name += ".exe"
}
return name
}
View on GitHub (pinned to 724551b9ae)
Solutions
- Fix ownership/permissions of the bin directory: sudo chown -R $USER ~/.hasura/plugins && chmod u+w ~/.hasura/plugins/bin.
- Check for immutability: lsattr <path> and clear with chattr -i if set.
- Close processes holding the binary (or reboot on Windows) and retry the uninstall.
- Retry the command if the link was concurrently removed (race).
Defensive patterns
Strategy: retry
Validate before calling
// ensure the containing directory is writable before uninstall
if info, err := os.Stat(filepath.Dir(linkPath)); err == nil {
if info.Mode().Perm()&0o200 == 0 { os.Chmod(filepath.Dir(linkPath), 0o755) }
} Try / catch
err := uninstall()
if err != nil && strings.Contains(err.Error(), "failed to remove the symlink") {
time.Sleep(100 * time.Millisecond)
err = uninstall() // covers TOCTOU races
} Prevention
- Never run the CLI with sudo for routine plugin operations.
- Keep antivirus exclusions for the plugins bin directory on Windows.
When it happens
Trigger: Calling Uninstall or createOrUpdateLink when os.Remove fails on the symlink: directory lacks write/execute permission, immutable file attribute set (chattr +i), file locked by another process on Windows, or a TOCTOU race where the link was already removed.
Common situations: The plugins bin directory is owned by root after running the CLI with sudo once, so later non-root runs cannot delete links; or on Windows an antivirus/terminal holds a handle to the plugin binary.
Related errors
- failed to resolve the symlink of the currently executed vers
- failed to create a symlink from %q to %q: %w
- writing metadata to file: %w
- error getting directory details: %w
- write file: %w
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/b655f1136d3ac9dc.
Report an issue: GitHub.