matryer/xbar · error

no plugin files

Error message

no plugin files

What it means

writePluginFiles copies the plugin's declared files into the installation directory. If the fetched metadata.Plugin has an empty Files slice there is nothing to install, so the installer aborts with errors.New("no plugin files").

Source

Thrown at pkg/plugins/install.go:108

	)
	for err == nil {
		count++
		candidateBaseName := fmt.Sprintf("%03d-%s", count, plugin.Filename)
		candidatePath = filepath.Join(i.PluginDir, candidateBaseName)
		_, err = os.Stat(candidatePath)
	}
	if !os.IsNotExist(err) {
		return "", err
	}
	return candidatePath, nil
}

// writePluginFiles iterates through the files defined for the plugin, and
// writes them to the plugin installation directory, and sets the entry point
// to be executable.
func (i Installer) writePluginFiles(dstPath string, plugin metadata.Plugin) error {
	if len(plugin.Files) == 0 {
		return errors.New("no plugin files")
	}
	if len(plugin.Files) > 1 {
		return errors.Errorf("only one plugin file supported: found %d.", len(plugin.Files))
	}
	for _, f := range plugin.Files {
		pluginFile := dstPath
		dir := path.Dir(pluginFile)
		if err := os.MkdirAll(dir, 0777); err != nil {
			return errors.Wrapf(err, "create directory %s for plugin", dir)
		}
		writer, err := os.Create(pluginFile)
		if err != nil {
			return errors.Wrapf(err, "create plugin file %s", f.Path)
		}
		defer writer.Close()
		reader := strings.NewReader(f.Content)
		if _, err := io.Copy(writer, reader); err != nil {
			return errors.Wrapf(err, "write plugin file %s", f.Path)

View on GitHub (pinned to d624239058)

Solutions

  1. Add the plugin source file to the files array in the plugin.json metadata
  2. Re-fetch the plugin metadata to get a complete descriptor
  3. Verify the registry response includes the plugin.files field before calling Install

Example fix

// before (plugin.json)
{ "name": "myplugin", "files": [] }
// after
{ "name": "myplugin", "files": ["myplugin.5m.py"] }
Defensive patterns

Strategy: validation

Validate before calling

// before Install: ensure metadata declares at least one file
if len(plugin.Files) == 0 {
    return fmt.Errorf("plugin %q has no files; check its plugin.json", plugin.Name)
}

Try / catch

// Go
if err := installer.Install(ctx, pluginPath); err != nil {
    if err.Error() == "no plugin files" {
        return fmt.Errorf("plugin descriptor incomplete (missing files): %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Install with a plugin whose metadata (from fetchPlugin or local metadata.Plugin struct) has Files == nil or len(Files) == 0, typically because the plugin.json descriptor omitted the files array.

Common situations: A plugin repository with a malformed or incomplete plugin.json; a registry/API response missing the files field due to server-side data issues; hand-constructed metadata.Plugin structs in tests.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of matryer/xbar@d624239058 (2026-09-02). Data as JSON: /api/errors/e9417231830afc5c. Report an issue: GitHub.