hasura/graphql-engine · error
could not remove plugin directory %q: %w
Error message
could not remove plugin directory %q: %w
What it means
After removing the bin symlink, Uninstall() deletes the plugin's versioned install directory with os.RemoveAll. Any error from that call is returned here, leaving the receipt file still present, so the plugin remains 'installed' from the tool's perspective.
Source
Thrown at cli/plugins/plugins.go:260
return errors.E(op, ErrIsNotInstalled)
}
return errors.E(
op,
fmt.Errorf("failed to look up install receipt for plugin %q: %w", name, err),
)
}
symlinkPath := filepath.Join(c.Paths.BinPath(), PluginNameToBin(name, IsWindows()))
if err := removeLink(symlinkPath); err != nil {
return errors.E(op, fmt.Errorf("could not uninstall symlink of plugin: %w", err))
}
pluginInstallPath := c.Paths.PluginInstallPath(name)
if err := os.RemoveAll(pluginInstallPath); err != nil {
return errors.E(
op,
fmt.Errorf("could not remove plugin directory %q: %w", pluginInstallPath, err),
)
}
pluginReceiptPath := c.Paths.PluginInstallReceiptPath(name)
err := os.Remove(pluginReceiptPath)
if err != nil {
return errors.E(
op,
fmt.Errorf("could not remove plugin receipt %q: %w", pluginReceiptPath, err),
)
}
return nil
}
func (c *Config) installPlugin(plugin Plugin, platform Platform) error {
var op errors.Op = "plugins.Config.installPlugin"View on GitHub (pinned to 724551b9ae)
Solutions
- Stop any running process using the plugin binary, then retry uninstall
- Fix ownership of the plugin install directory (chown -R) or run the uninstall with sufficient privileges
- If the directory is on a read-only or locked mount, remount writable / release the lock and retry
- As a last resort remove the plugin install directory manually, then remove the leftover receipt file so the plugin no longer appears installed
Defensive patterns
Strategy: retry
Validate before calling
installDir := cfg.Paths.PluginInstallPath(name)
if err := os.RemoveAll(installDir); err == nil {
// pre-clear the directory so Uninstall's RemoveAll is a no-op
} Try / catch
err := cfg.Uninstall(name)
if err != nil && strings.Contains(err.Error(), "could not remove plugin directory") {
// stop running plugin processes, fix ownership, then retry — the operation is idempotent
} Prevention
- Terminate plugin processes before uninstalling (avoids ETXTBSY on Linux)
- Don't keep shells/terminals cd'd into plugin install directories
- Avoid mixed sudo/non-sudo installs that leave root-owned files in the install dir
When it happens
Trigger: Uninstall fails at os.RemoveAll(PluginInstallPath(name)): permission denied on a file inside the install dir (often a still-executing binary giving ETXTBSY on Linux), read-only filesystem, or the path being held open by another process.
Common situations: The plugin process is still running (binary busy, ETXTBSY); install dir owned by root from a previous sudo install; plugins dir on a network/read-only mount; Windows file locking by antivirus or a running shell with cwd inside the dir.
Related errors
- could not uninstall symlink of plugin: %w
- could not remove plugin receipt %q: %w
- could not create staging dir %q: %w
- write plugin receipt %q: %w
- failed to open index file: %w
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/70df7200ab6637ce.
Report an issue: GitHub.