hasura/graphql-engine · error

failed to scan plugins in index directory: %w

Error message

failed to scan plugins in index directory: %w

What it means

LoadPluginListFromFS enumerates all plugin manifest files via findPluginManifestFiles before loading them; this error means that directory scan failed. It wraps the underlying filesystem error from walking the plugins index directory.

Source

Thrown at cli/plugins/scanner.go:69

	if err != nil {
		return nil, errors.E(op, err)
	}

	return out, nil
}

// LoadPluginListFromFS will parse and retrieve all plugin files.
func (c *Config) LoadPluginListFromFS(indexDir string) (Plugins, error) {
	var op errors.Op = "plugins.Config.LoadPluginListFromFS"

	indexDir, err := filepath.EvalSymlinks(indexDir)
	if err != nil {
		return nil, errors.E(op, err)
	}

	files, err := c.findPluginManifestFiles(indexDir)
	if err != nil {
		return nil, errors.E(op, fmt.Errorf("failed to scan plugins in index directory: %w", err))
	}

	return c.LoadPlugins(files), nil
}

// LoadPluginByName loads a plugins index file by its name. When plugin
// file not found, it returns an error that can be checked with stderrors.Is(err, fs.ErrNotExist).
func (c *Config) LoadPluginByName(pluginName string) (*PluginVersions, error) {
	var op errors.Op = "plugins.Config.LoadPluginByName"

	c.Logger.Debugf("loading plugin %s", pluginName)

	if !IsSafePluginName(pluginName) {
		return nil, errors.E(op, fmt.Errorf("plugin name %q not allowed", pluginName))
	}

	files, err := c.findPluginManifestFiles(c.Paths.IndexPluginsPath())
	if err != nil {

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Check permissions and reachability of Paths.IndexPluginsPath(): ls -la on the directory
  2. If the directory is a broken symlink or a file, remove it and recreate as a directory
  3. For network-mounted home dirs, verify the mount is healthy and retry

Example fix

# before
mycli plugin list
# Error: failed to scan plugins in index directory: ... permission denied

# after
sudo chown -R $(whoami) ~/.mycli/plugins && mycli plugin list
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(cfg.Paths.IndexPluginsPath())
if err != nil || !info.IsDir() { /* recreate dir or abort with clear message */ }

Try / catch

plugins, err := cfg.LoadPluginListFromFS()
if err != nil {
	if strings.Contains(err.Error(), "failed to scan plugins") {
		// filesystem issue with index dir: surface a permissions hint
	}
}

Prevention

When it happens

Trigger: Calling Config.ListPlugins when the plugins index directory cannot be read: it is a file instead of a directory, permissions deny traversal, or an I/O error occurs during the directory walk.

Common situations: Plugins index dir was replaced by a symlink to an unreachable location; directory permissions were tightened (chmod 700 by another user); NFS/network mount dropped mid-walk.

Related errors


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