hasura/graphql-engine · error
failed to read the symlink in %q: %w
Error message
failed to read the symlink in %q: %w
What it means
Thrown when os.Lstat fails for a path that should be a plugin symlink during uninstall/relink, and the error is anything other than 'file does not exist' (which is treated as success). The wrapped error typically indicates permission problems on the parent directory or an I/O failure reading the file's metadata.
Source
Thrown at cli/plugins/util.go:236
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))
}
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, "-", "_")
View on GitHub (pinned to 724551b9ae)
Solutions
- Check permissions on the full path: namei -l ~/.hasura/plugins/bin/<plugin> and fix with chmod/chown.
- Verify no path component is a file rather than a directory; recreate the bin directory if corrupted.
- Temporarily disable antivirus/lockers on Windows and retry uninstall.
- As a last resort, manually delete the plugins bin directory and let the CLI recreate it.
Defensive patterns
Strategy: validation
Validate before calling
// verify the path is statable before uninstalling
if _, err := os.Lstat(linkPath); err != nil && !errors.Is(err, fs.ErrNotExist) {
log.Fatalf("cannot stat %s: %v", linkPath, err)
} Try / catch
if err := plugins.Uninstall(...); err != nil {
if strings.Contains(err.Error(), "failed to read the symlink") {
// directory-level permission problem; fix and retry
}
} Prevention
- Avoid running the CLI under sudo so the bin directory stays user-owned.
- Keep the plugins directory on a local filesystem, not a restricted network mount.
When it happens
Trigger: Calling Uninstall or createOrUpdateLink when os.Lstat on the symlink path returns a non-ErrNotExist error: permission denied on the containing directory, a path component that is not a directory, or a filesystem/IO error.
Common situations: The plugins bin directory or an ancestor was made read-only, the directory was replaced by a Docker bind mount with odd permissions, or an antivirus/locking mechanism on Windows interferes with stat calls.
Related errors
- writing metadata to file: %w
- error getting directory details: %w
- write file: %w
- cannot create global config directory: %w
- write global config file: %w
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/13f049965509ec9c.
Report an issue: GitHub.